I'm trying to write a function which will take a string literal and return an object with a single field whose name is that string literal. I can write a function that does what I want, but I don't know how to express the constraint that its argument type be a string literal.
The closest I've got is using a generic type which extends string
. This permits string literal types, but also unions of string literal types and the type string
, which I don't want to be passed to my function.
This compiles, and does what I want, provided that K
is a string literal type. Note that type assertion wasn't necessary in typescript 3.4 but it is required in 3.5.
function makeObject<K extends string>(key: K): { [P in K]: string } {
return { [key]: "Hello, World!" } as { [P in K]: string };
}
If K
is anything other than a string literal, the return type of this function won't be the same as the type of the value it returns.
The 2 avenues I can imagine for making this work are:
- constrain K to be only string literals
- express that the return type be an object with a single field whose name is a value in K (less satisfying, but at least the type of the function will be honest)
Can typescript's type system express either of these?
If I remove the type assertion in typescript 3.5 I get the error:
a.ts:2:3 - error TS2322: Type '{ [x: string]: string; }' is not assignable to type '{ [P in K]: string; }'.
2 return { [key]: "Hello, World!" };