Home > Software design >  Defining a TypeScript object type where the type of a property depends on the value of another one o
Defining a TypeScript object type where the type of a property depends on the value of another one o

Time:02-03

Please check the following example:

type MyLiterals = 'a' | 'b'

type MyObject<T extends MyLiterals> = {
    a: T,
    b: T extends 'a' ? number : string
}

// thit works
let obj2: MyObject<'b'> = {
    a: 'b',
    b: ''
}

// Generic type 'MyObject' requires 1 type argument(s)
let obj1: MyObject = {
    a: 'b',
    b: ''
}

Is there a way to achieve what I am trying to do with the second example, where the value of the generic is inferred by the value assigned to the first property?

CodePudding user response:

Alternatively you can create a union of all possible pairs.

Here I leveraged distributive conditional types to do it:

type MyObjectFactory<T extends MyLiterals> = T extends any ? {
    a: T,
    b: T extends 'a' ? number : string
} : never

type MyObject = MyObjectFactory<MyLiterals>

playground

Another way to write it:

type MyObject = MyLiterals extends infer T ? T extends any ? {
    a: T,
    b: T extends 'a' ? number : string
} : never : never

CodePudding user response:

Is that ok with a function ?

function setIt<T extends MyLiterals>(a:T, b : T extends 'a' ? number : string) : MyObject<T>{
    return {a,b}
}

let obj1;

obj1 = setIt('a',12); // OK
obj1 = setIt('b',12); // Do not compile 
  • Related