Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Infer object types by sibling property – Typescript

Is it possible to assert properties of an object based on another property within that same object?

But how can I infer the types for values based on the value of type property?

type StepKeys = "Test1" | "Test2";

interface objectMap {
    "Test1": {
        name: string
    },
    "Test2": {
        age: number
    }
};

interface Step<T extends StepKeys = StepKeys> {
    type: T;
    value: objectMap[T]
};

const steps: Record<string, Step> = {
    "Step1": {
        type: "Test1",
        value: {

        }
    }
}

Here types for values are a union of { name: string; } | { age: number; }.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is it possible to infer it’s possible values?

Typescript

>Solution :

Hi should you want to effectively discriminate this union, the type parameter should not be a union, instead seek to "push" the union one type up. This is because we want each Step type to have it’s own unique type parameter, instead of the union of possible type parameters. So a small change, but accomplishes what you want.

const steps: Record<string, Step<'Test1'> | Step<'Test2'>> = {
    "Step1": {
        type: "Test1",
        value: {
            // infer ?
            age: 11,
// ^^^ correctly throws error 
// Object literal may only specify known properties, and 'age' does not exist in type '{ name: string; }'.(2322)
            name: 'test',
        }
    }
}

Using an indexed access map type you can create a discriminated union automatically if there are a lot more key/value pairs.

type Steps = Record<string, {
    [key in StepKeys]: Step<key>
}[StepKeys]>

View on TS Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading