Conditional Types - Typescript
Problem
Given a type like the one below:
type Parent = {
option: "A" | "B";
children: { subOption: { a: true } | { b: true } };
};
It's not possible to guarantee that children will have the correct subOption.
const foobar: Parent = {
// this is ok
option: "A",
children: { subOption: { a: true } },
};
const foobar2: Parent = {
// this is wrong, but the compiler cannot ensure the correct type
option: "A",
children: { subOption: { b: true } },
};
How to fix this
To guarantee that children will have the correct type use conditional types. So, the compiler is able to infer the correct type.
type Parent<Option extends "A" | "B"> = {
option: Option;
children: {
subOption: Option extends "A"
? { a: true }
: Option extends "B"
? { b: true }
: never;
};
};
const foobar: Parent<"A"> = {
option: "A",
children: { subOption: { a: true } },
};
const foobar2: Parent<"A"> = {
option: "A",
// @ts-expect-error
children: { subOption: { b: true } },
Example
Using conditional type we can set the properties of a column by the table's responsive type. Like this:
type ResponsiveType = "shorten" | "movable";
type ResponsiveTypePropsForShorten = { visible: boolean };
type ResponsiveTypePropsForMovable = { move: boolean };
type ResponsiveTypeProps<R extends ResponsiveType> = R extends "shorten"
? ResponsiveTypePropsForShorten
: R extends "movable"
? ResponsiveTypePropsForMovable
: never;
type Table<R extends ResponsiveType> = {
responsiveType: R;
columns: Column<R>[];
};
type Column<R extends ResponsiveType> = {
responsiveTypeProps: ResponsiveTypeProps<R>;
};
const table1: Table<"shorten"> = {
responsiveType: "shorten",
columns: [{ responsiveTypeProps: { visible: true } }],
};
const table2: Table<"movable"> = {
responsiveType: "movable",
columns: [{ responsiveTypeProps: { move: false } }],
};
If you want to see the full version of the example above click here