'Typescript: a object only allow one Specific key

I want to define a object only have one specific key,and the key depend on a type, for example:

type keys = 'a' | 'b' | 'c'

// thats ok
obj = {
 a: 'string'
}

// no
obj = {
 a: 'string',
 b: 'string'
}

// no
obj = {
 a: 'string',
 d: 'string'
}

// no
obj = {
 d: 'string'
}

I can only think of one way like:

type MyObject = {
 [key in keys]?: string
}

but its just half-measures, so is there a good or perfect way?



Solution 1:[1]

It is possible to do this by using some types to create a discriminated union of values.

type CreateObjHelper<Keys extends string> = {
    [K in Keys]: {
        [K2 in Keys]?: K2 extends K ? string : never
    }
}
type CreateObjOneKey<Keys extends string> = CreateObjHelper<Keys>[keyof CreateObjHelper<Keys>]

type MyKeys = 'a' | 'b' | 'c'

type MyObjOneKey = CreateObjOneKey<MyKeys>

const obj: MyObjOneKey = {
    a: ''
}
//...

It will work on the test cases you've given here.

See it in action on TS Playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cody Duong