'Why isn't T[string] a valid object lookup type in TypeScript?
I'm trying to better understand how lookup types work in TypeScript.
I have seen T[number] used as a lookup type that gives a union, like follows:
type Tuple = ['cat', 'dog', 'elephant']
type TupleToUnion = Tuple[number]
// gives union type: 'cat' | 'dog' | 'elephant'
I wanted to use T[string] to do a similar lookup on an object type. The result is not successful:
type Obj = { 'cat': 'cat', 'dog': 'dog', 'elephant': 'elephant' }
type ObjToUnion = Obj[string]
// Type 'Obj' has no matching index signature for type 'string'. (2537)
Why does T[number] work as a lookup type and T[string] does not?
Solution 1:[1]
An array type has an interface similar to this:
interface ArrayLike<T> {
length: number;
[key: number]: T;
}
Therefore, ArrayType[number] is correct because the interface specified that all keys will be number type.
For a custom object type, like the one you use in example:
type Obj = {
'cat': 'cat';
'dog': 'dog';
'elephant': 'elephant'
}
While all keys are indeed of string type, only 3 specific string keys are valid: cat, dog, elephant. Therefore, doing Obj[string] is wrong because string represents all string values (like abc, hello, etc), not just the 3 keys.
To use Obj[string], you would need to declare it the way similar to ArrayLike:
type Obj = {
[key: string]: string;
}
type ObjToUnion = Obj[string]; // ok
To get only the keys from an object, you can use keyof operator:
type Obj = {
'cat': 'cat';
'dog': 'dog';
'elephant': 'elephant'
}
type ObjToUnion = Obj[keyof Obj];
EDIT
This is called index signature. Its documentation can be found here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
