Say, if I have two union type in TypeScript, for example:
const a = 1;
const b = 2;
type AB = typeof a | typeof b;
type AABB = 'aa' | 'bb';
type Test = AB | AABB;
const obj = {
a: 'aa',
b: 'bb'
}
const t1: Test = 'aa';
const t2: Test = obj.a;
'aa' can assign to t1, but obj.a
can not assign to t2, why?
CodePudding user response:
Because your obj
's type is:
const obj: {
a: string;
b: string;
}
The object properties are interpreted by TS to be just strings, not specific strings. So obj.a
is a string, but a Test
is a (union of) specific strings, so it's not assignable.
Change to
const obj = {
a: 'aa',
b: 'bb'
} as const;
so that the properties aren't widened, and your code will work as expected.
CodePudding user response:
Just to add on to the answer from @CertainPerformance, as const
is called a const assertion, and makes the typescript compiler interpet all literals with in object as their narrowed, readonly types.
To explain, for your case:
const obj = {
a: 'aa',
b: 'bb'
};
type Inferred = {
a: string,
b: string
};
Alternatively:
const obj = {
a: 'aa',
b: 'bb'
} as const;
type Inferred = {
readonly a: 'aa',
readonly b: 'bb'
};