say for example I have this type in typescript:
enum NumberOrStringType {
NUMBER,
STRING,
}
type NumberOrString = {
dataType: NumberOrStringType,
data: string | number;
};
and later in the code:
const numOrString: NumberOrString = { dataType: NumberOrStringType.NUMBER, data: 10 };
if (numOrString.dataType === NumberOrStringType.NUMBER) {
const num: number = numOrString.data;
...
} else {
const str: string = numOrString.data;
...
}
Unfortunately, I get errors saying that type string | number is not assignable to type number and type string | number is not assignable to type string.
I know I can just cast num and str by using as number and as string respectively, but is there a way to tell typescript to determine the type of data via the enum is has been assigned, or by narrowing the type by using an if statement?
>Solution :
You need to use a discriminated union: otherwise there is no way for Typescript to infer that when dataType is NumberOrStringType.NUMBER that data is always number, and vice versa for string.
type NumberOrString = {
dataType: NumberOrStringType.NUMBER;
data: number;
} | {
dataType: NumberOrStringType.STRING;
data: string;
}
Once you do that, you can use the satisfies operator to ensure TypeScript checks if your object satisfies the type, and your code should work:
const numOrString = { dataType: NumberOrStringType.NUMBER, data: 10 } satisfies NumberOrString;
if (numOrString.dataType === NumberOrStringType.NUMBER) {
const num = numOrString.data;
} else {
const str = numOrString.data;