Reputation: 2299
Why doesn't TypeScript emit "a" | "b"
for the type of test2
? My IDE's IntelliSense correctly infers that test2
is of type of "a" | "b"
, but the emitted type declaration is just "string"
.
// index.ts
export const test1 = true ? ('a' as const) : ('b' as const);
export const test2 = true ? 'a' : 'b';
// index.d.ts
export declare const test1: "a" | "b";
export declare const test2: string;
// tsconfig.json
{
"compilerOptions": {
"composite": true,
"emitDeclarationOnly": true,
}
}
Upvotes: 0
Views: 67
Reputation: 25029
Using type
and typeof
tp debug it:
export const test1 = true ? ('a' as const) : ('b' as const);
type T1 = typeof test1; // 'a' | 'b'
export const test2 = true ? 'a' : 'b';
type T2 = typeof test2; // 'a' | 'b'
In both cases, the type is 'a' | 'b'
. Is TypeScript ignoring true ?
in the conditional expression. It is simply inferring the type In both sides of the expression 'a' : 'b'
.
Because string
is compatible with "a" | "b"
and you don't use as const
, TypeScript will use string
. This is done to prevent compatibility issues with libraries. This is not obvious in your example. but take a look at how it works when you use objects:
export const test1 = {
a: 'a',
b: 'b'
};
type T1 = typeof test1; // { a: string, b: string }
export const test2 = {
a: 'a',
b: 'b'
} as const;
type T2 = typeof test2; // { a: 'a', b: 'b' }
It is the same, but as you can imagine, using 'a' | 'b'
in object values instead of string
by default could lead to many issues in existing libraries; this is why unless you use as const,
TypeScript will go for string
.
Upvotes: 0