简体   繁体   中英

How can I tell Typescript that two object keys must be the same?

I want to define a type over a JS/TS record (ie, something with keys and values):

type Args<R extends object> = {
  foo: keyof R
  bar: keyof R
}

How can I tell Typescript that I want foo and bar to be the same keyof R ?

I can do this:

type Args<R extends object, K extends keyof R> = {
  foo: K
  bar: K
}

But then all clients of the Args type to have to manually specify type K :

type Pizza = {
  name:   string
  radius: int
}

const myArgs: Args<Pizza, 'name'> = { foo: 'name', bar: 'name' }

Typescript should be able to infer this, I would think. But how do I write the type?

This is possible. You can create a union of all possible foo and bar combinations of a given generic type like this:

type Args<R extends object> = {
  [K in keyof R]: {
    foo: K,
    bar: K
  }
}[keyof R]

This will lead to the desired behaviour:

type Pizza = {
  name:   string
  radius: number
}

const myArgs1: Args<Pizza> = { 
  foo: 'name', 
  bar: 'name' 
}
const myArgs2: Args<Pizza> = { 
  foo: 'name', 
  bar: 'radius' 
} // Error: "name"' is not assignable to type '"radius"

Playground

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