带有排除和类型保护的TypeScript并集
为什么下面的代码有错误 我想知道这是TypeScript编译器的一个bug带有排除和类型保护的TypeScript并集,typescript,Typescript,为什么下面的代码有错误 我想知道这是TypeScript编译器的一个bug A型= | { 类型:“a”; a:弦; } | { 类型:“b”; b:弦; }; X型={ x:字符串; }&A; XX型=拾取和{ x:数字; }; 常数x:XX={}如有; 如果(x.type=='a'){ //类型“XX”上不存在属性“a” 控制台日志(x.a); }您看到的只是联合类型工作方式的结果。联合(除非缩小范围)仅允许访问公共属性。因此,当您说keyof X时,将出现在结果字符串文字联合中的唯一属性
A型=
| {
类型:“a”;
a:弦;
}
| {
类型:“b”;
b:弦;
};
X型={
x:字符串;
}&A;
XX型=拾取和{
x:数字;
};
常数x:XX={}如有;
如果(x.type=='a'){
//类型“XX”上不存在属性“a”
控制台日志(x.a);
}
您看到的只是联合类型工作方式的结果。联合(除非缩小范围)仅允许访问公共属性。因此,当您说keyof X
时,将出现在结果字符串文字联合中的唯一属性是X
(它不依赖于联合)和type
,这两个联合成员都通用Pick
也在幕后使用keyof
,因此有相同的问题,它将能够选择所有工会成员共有的任何工会成员
您可以获得所需的行为,但不能直接使用keyof
和Pick
。您需要在具有裸类型参数的条件类型中使用。条件类型将分布在联合的成员上(您可以阅读有关此行为的更多信息或更简明的版本),允许我们对联合的每个成员而不是整个联合应用keyof
和Pick
type A =
| {
type: 'a';
a: string;
}
| {
type: 'b';
b: string;
};
type X = {
x: string;
} & A;
type UnionKeys<T> = T extends any ? keyof T : never;
type UnionPick<T, K extends UnionKeys<T>> = T extends any ? Pick<T, Extract<K, keyof T>> : never
type XX = UnionPick<X, Exclude<UnionKeys<X>, 'x'>> & {
x: number;
};
const x: XX = {} as any;
if (x.type === 'a') {
console.log(x.a);
}
A型=
| {
类型:“a”;
a:弦;
}
| {
类型:“b”;
b:弦;
};
X型={
x:字符串;
}&A;
类型UnionKeys=T扩展任何?基特:永远不会;
类型UnionPick=T扩展任何?选择:从不
XX型=联合拾取&{
x:数字;
};
常数x:XX={}如有;
如果(x.type=='a'){
控制台日志(x.a);
}