2
const a =<T extends unknown>(arg:T)=>arg

const a_ = a(1) // type is 1

const b =<T extends unknown>(arg:T)=>({arg})

const b_= b(1) // type is {arg: number}, expect {arg: 1}

const c =<T extends unknown>(arg:T)=>({arg})

const c_= b(1 as const) // type is {arg: 1}, ok but degrade dev experience

In the example, if I return an object where the member type is based on the generic, it is widen back to number even if the generic type is 1

problem solved if I give it const assertion, but it is not a good dev experience

How can I stop this widening behaviour?

Note: T must extends unknown

playground

Acid Coder
  • 2,047
  • 15
  • 21
  • 1
    Does this answer your question? [How can I hint to the Typescript compiler to infer string literal types for properties?](https://stackoverflow.com/a/47606390/438273) – jsejcksn Mar 22 '22 at 16:32
  • 1
    yes, seem like the answer is 'not possible' – Acid Coder Mar 22 '22 at 16:54

1 Answers1

0

Just add the type to the function call

const c = <T extends unknown>(arg: T) => ({arg})

const d: {arg: 1} = c<1>(1)

console.log(d.arg) // 1

In this way TS does not deduce the type from the argument (number in this case), it will use the type you give to him (<1>)

Nullndr
  • 1,624
  • 1
  • 6
  • 24