Simple example (type of x
):
const x = {
'a': { key: 'a' },
'b': { key: 'b' },
'c': { key: 'c' },
// ...
};
If I knew all a
/ b
/ c
/ …
in advance, I could do { [TKey in 'a'|'b'|'c']: { key: TKey } }
.
But can I define a type so that for any key k
value must have { key: k }
without having a full list of keys in advance?
You can let the compiler message guide you:
This is what you would like:
type Foo<K> = { [TKey in K]: { key: TKey } }
but it doesn't compile because
Type 'K' is not assignable to type 'string | number | symbol'.
Type 'K' is not assignable to type 'symbol'.
Assuming (based on your example) you want to work only with string keys:
type Foo<K extends string> = { [TKey in K]: { key: TKey } }
So you can pass your own narrowed type that's based on string:
type X = Foo<'a' | 'b' | 'c'>
type X = {
a: {
key: "a";
};
b: {
key: "b";
};
c: {
key: "c";
};
}
I've been searching for this as well. I experimented in TypeScript a bit and came up with this solution:
type ObjectWithKey<obj extends {[key: string]: any}> = {
[k in keyof obj]: {key: k};
}
declare function createObjectWithKeys<T extends {[key: string]: any} & ObjectWithKey<T>>(input: T): T;
// This does not compile
const x = createObjectWithKeys({
a: 1,
b: {key: 'c'},
c: {key: false}
})
// This does compile
const x = createObjectWithKeys({
a: {key: 'a'},
b: {key: 'b'},
c: {key: 'c'}
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.