Generate a const typed object in TypeScript

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;
}

Solution 1:

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