简体   繁体   中英

Stricter return type for object literal in Typescript

In this code

const s = "myKey" as const;
const myF = () => ({
  [s]: 0,
});

the type of myF is function myF(): {[p: string]: number, myKey: number}

where return type is {[p: string]: number, myKey: number}

As you can see, unwanted [p: string]: number leaks here.

How do I make my return type an expected {myKey: number} without explicit type annotation?

I don't want to go into explicit annotation just yet since I got some types with a LOT of fields.

This is the default behavior of TypeScript. It always evaluates computed property to string.

You can write custom helper to create objects:

const s = "myKey";

const record = <Prop extends PropertyKey, Value>(prop: Prop, value: Value) => 
  ({ [prop]: value }) as Record<Prop, Value>

// const myF: () => Record<"myKey", number>
const myF = () => record(s, 42)

Playground

You don't need to use as const

Be aware that this solution has a drawback.

const drawback = record<'myKey' & { hello?: 'world' }, 42>('myKey', 42).myKey // error

Hence, you better to avoid using explicit generics for this function

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM