当没有类型注释时,Typescript 抱怨受歧视的联合类型
Typescript complains about discriminated union types when there is no type annotation
在我看来,在没有任何类型注释的情况下,打字稿无法识别可区分的联合类型。我错过了什么吗?这有什么原因吗?
export type Stuff = AType | BType
export type AType = { status: Kind.A; name: string }
export type BType = { status: Kind.B; quantity: number }
export enum Kind {
A,
B,
}
function PlayWithStuff(stuff: Stuff) {
console.log('some stuff', stuff)
}
const stuff = {
status: Kind.B,
quantity: 2,
}
PlayWithStuff(stuff)
// ^^^^^
// Argument of type '{ status: Kind; quantity: number; }' is not assignable to parameter of type 'Stuff'.
// Type '{ status: Kind; quantity: number; }' is not assignable to type 'BType'.
// Types of property 'status' are incompatible.
// Type 'Kind' is not assignable to type 'Kind.B'.
const secondStuff: Stuff = {
status: Kind.B,
quantity: 2,
}
PlayWithStuff(secondStuff)
// OK, the type annotation on `secondStuff` fixes the problem
当初始化对象字面量时,Typescript 将推断 属性 类型,但不是常量,因为它们不是只读的。
因此 stuff
的类型将是 { status: Kind, quantity: number }
,因为您稍后可以将其更改为:
const stuff = {
status: Kind.B,
quantity: 2,
};
stuff.status = Kind.A;
所以现在它不能分配给 BType
(也不能分配给 AType)。
您可以使用 as const
:
const stuff = {
status: Kind.B,
quantity: 2,
} as const;
现在类型被推断为 { readonly status: Kind.B, readonly quantity: 2}
,它始终可分配给 BType。
或者你可以做你所做的,只是给它类型注释:
const stuff: BType = {
status: Kind.B,
quantity: 2,
};
stuff.status = Kind.A; // Errors
在我看来,在没有任何类型注释的情况下,打字稿无法识别可区分的联合类型。我错过了什么吗?这有什么原因吗?
export type Stuff = AType | BType
export type AType = { status: Kind.A; name: string }
export type BType = { status: Kind.B; quantity: number }
export enum Kind {
A,
B,
}
function PlayWithStuff(stuff: Stuff) {
console.log('some stuff', stuff)
}
const stuff = {
status: Kind.B,
quantity: 2,
}
PlayWithStuff(stuff)
// ^^^^^
// Argument of type '{ status: Kind; quantity: number; }' is not assignable to parameter of type 'Stuff'.
// Type '{ status: Kind; quantity: number; }' is not assignable to type 'BType'.
// Types of property 'status' are incompatible.
// Type 'Kind' is not assignable to type 'Kind.B'.
const secondStuff: Stuff = {
status: Kind.B,
quantity: 2,
}
PlayWithStuff(secondStuff)
// OK, the type annotation on `secondStuff` fixes the problem
当初始化对象字面量时,Typescript 将推断 属性 类型,但不是常量,因为它们不是只读的。
因此 stuff
的类型将是 { status: Kind, quantity: number }
,因为您稍后可以将其更改为:
const stuff = {
status: Kind.B,
quantity: 2,
};
stuff.status = Kind.A;
所以现在它不能分配给 BType
(也不能分配给 AType)。
您可以使用 as const
:
const stuff = {
status: Kind.B,
quantity: 2,
} as const;
现在类型被推断为 { readonly status: Kind.B, readonly quantity: 2}
,它始终可分配给 BType。
或者你可以做你所做的,只是给它类型注释:
const stuff: BType = {
status: Kind.B,
quantity: 2,
};
stuff.status = Kind.A; // Errors