I am trying to generate a const
typed object by passing in a string I want to use as the type, is this possible, I have tried the below and it’s bringing out the wrong type.
const test = <T> (name: T) => { const hi: { name: T } = { name } as const return hi } const test1 = test('hello')
I’d like this to be of type
{ name: 'hello'; }
But instead it’s of type
{ name: string; }
Advertisement
Answer
In order to infer literal type of an argument, usually you need to add appropriate constraint to your generic argument. See this example:
function test<T extends string>(name: T) { return { name }; } const test1 = test('hello') // {name:"hello"}
If you are interested in more examples, you can check my article
If you want to add some validation, you can use conditional type:
// Forbids using underscore as a prefix type IsAllowed<T extends string> = T extends `_${string}` ? never : T function foo<T extends string>(name: IsAllowed<T>) { return { name }; } const test1 = foo('hello') // ok const test2 = foo('_hello') // expected error
Or you may use this utility type :
type IsLiteral<T extends string> = T extends string ? string extends T ? never : T : never function test<T extends string>(name: IsLiteral<T>) { return { name }; }
If you want to allow only string literals