Home > other >  Typescript infer type parameter
Typescript infer type parameter

Time:10-15

I want to restrict the type of one object property based on value of another property:

type DataType = "string"|"number"|"date";

type DataTypeMapping = {
    "string": string;
    "number": number;
    "date": string;
}

interface LinkedTypesSample <T extends DataType> {
    typ: T;
    value: DataTypeMapping[T];
}

now I can create type checked objects like so:

const stringInstance: LinkedTypesSample<"string"> = {
    typ: "string",
    value: "abc"
}

const numberInstance: LinkedTypesSample<"number"> = {
    typ: "number",
    value: 1
}

The question is - is it possible to skip type parameter of LinkedTypesSample? Looks like type parameter might be inferred from typ.

I tried to specify(naively) default type parameter like so:

interface LinkedTypesSample <T extends DataType = DataType> {
    typ: T;
    value: DataTypeMapping[T];
}

but in this case type checks stop work.

Playground

Edit: Ideally, I don't want 'LinkedTypesSample' to expose type parameter at all. I just want to express simple thought: one property must have certain type according to value or type of another property.

CodePudding user response:

You can try distributive conditional type. Basically create the type in two steps:

type MapType<U> = U extends DataType ? {
    typ: U,
    value: DataTypeMapping[U]
 } : never;

type LinkedTypesSample = MapType<DataType>;

// works
const stringInstance: LinkedTypesSample = {
    typ: "string",
    value: "abc"
}

const numberInstance: LinkedTypesSample = {
    typ: "number",
    value: 1
}

// error
const stringInstance2:  LinkedTypesSample = {
    typ: 'string',
    value: 1
}

playground.

  • Related