1

For example, if I am attaching additional data (in the form of key-value pairs, where the keys are strings) to an array instance, how can I extend the type of this instance of an array to allow for this additional data?

const associativeArray: string[] & Record<string, string> = ['some', 'array', 'data']
/*
Type 'never[]' is not assignable to type 'string[] & Record<string, string>'.
  Type 'never[]' is not assignable to type 'Record<string, string>'.
    Index signature is missing in type 'never[]'.ts(2322)
*/

associativeArray.customKey = 'customValue'
3
  • You could type it [...] as any for the initial assignment. Commented Jun 5, 2019 at 20:16
  • This seems dangerous. Are the keys of the key-value pairs known at compile time? Do you want those keys to show up in the length property, and can you guarantee that array methods like push wouldn't show up as keys? Commented Jun 5, 2019 at 20:54
  • As in JavaScript, associativeArray.customKey = 'customValue' would not affect the length, so I would not want the custom keys to affect the array length. I can also guarantee that array methods wouldn't get overridden, but would that guarantee be possible in TypeScript as well? Commented Jun 5, 2019 at 21:04

1 Answer 1

1

You can extend array types since Typescript 1.6.

class MyArray extends Array<string> {
  customKey?: string;
}

However, doing so with arbitrary string keys is probably a bad idea, because doing so with numeric strings will still affect Array behavior like length, and because you can overwrite Array properties and methods in Javascript and Typescript both. If you allow arbitrary string keys, you will probably lose many of the benefits of typing your object.

foo = ["a", "b", "c"];
console.log(foo.length);                        // 3
foo.arbitraryString = "arbitrary";
console.log(foo.length);                        // 3
foo["anotherArbitraryString"] = "arbitrary";
console.log(foo.length);                        // 3
foo["3"] = "d";
console.log(foo.length);                        // 4
foo["push"] = () => console.log("Oops.");
foo.push("e");                                  // Oops.

[Fiddle]

And in any case, it is equivalent and more idiomatic to use [key: string]: string as a property than a Record<string, string>.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.