Typescript联合类型已损坏?(使用对象类型和对象文字时)
例如Typescript联合类型已损坏?(使用对象类型和对象文字时),typescript,union-types,Typescript,Union Types,例如 interface Bird { fly(): void; layEggs(): void; } interface Fish { swim(): void; layEggs(): void; } declare function getSmallPet(): Fish | Bird; let pet = getSmallPet(); pet.layEggs(); 1例-良好 interface Birds { flys: boolean;
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
declare function getSmallPet(): Fish | Bird;
let pet = getSmallPet();
pet.layEggs();
1例-良好
interface Birds {
flys: boolean;
layEggs: string;
}
interface Fish {
swim: number;
layEggs: string;
}
declare let k: Fish & Birds;
k = { flys:true, layEggs:"", swim:3}
2例-良好
interface Birds {
flys: boolean;
layEggs: string;
}
interface Fish {
swim: number;
layEggs: string;
}
declare let k: Fish & Birds;
k = { flys:true, layEggs:"", swim:3}
3例-良好
4个示例-损坏
在第四个例子之前一切都是完美的。。。太让人困惑了
应该是k={layEggs:“}
证明:
interface Bird {
fly: number;
layEggs: string;
}
type g1 = keyof Bird
interface Fish {
swim: boolean;
layEggs: string;
}
type g2 = keyof Fish
type PetALL= keyof( Bird & Fish )
// let all1: EmployeeAll = "fly"
// let all2: EmployeeAll = "email"
// let all3: EmployeeAll = "layEggs"
type Pet = keyof( Bird | Fish )
// let only: Employee = "layEggs"
使用的编辑器(默认设置)
澄清问题
问题是为什么在下一种情况下允许输入:
interface Birds {
flys: boolean,
layEggs: string
}
interface Fish {
swim: number,
layEggs: string,
}
declare let k: Fish | Birds;
k = {}
不仅仅是k={layEggs:}
正如您在4示例中所看到的-断开
以及此SINTAX的工作原理
5示例-修复
当我使用联合时,关于对象文字的规则似乎不起作用,当使用对象类型时,TS开始像预期的那样抱怨 我能说的是,TS就是这样产生的,TS中还有其他数百个bug和意外行为需要我去学习,但总体来说可能没有更好的 1使用类型 2使用接口 很难提出一个问题,谢谢你@vlaz、@yury tarabanko、@jcalz、@dane brouwer
这是TS目前的一项功能。我不会在TS中使用对象文本,而是使用函数重载模式。我建议您将问题限制在您认为实际被破坏的唯一示例。目前它毫无意义。Esp命名
type Employee=keyof(Bird | Fish)
我很难理解你的问题是什么(keyof A | B)
=(keyof A&keyof B)
并不意味着A | B
类型的对象只能具有A
和B
的公共属性;这意味着给定类型为A | B的对象,您可以确定的唯一键就是这些键。任何A | B
类型的对象必须具有A
或B
的所有(必需)属性。也就是说,AA
是有效的A | B
,AB
是有效的A | B
k={flys:true,layEggs:,swim:3}
可分配给鸟和鱼。所以,这是正确的。您可以将其传递给函数catch(x:Fish)
或函数watch(x:Birds)
。如果它只有laysegs
,那么你既不能把它传给catch
也不能传给watch
@DaneBrouwer,我是说,它是。TS系统有一个根本性的问题,使得它不健全,比如。这不是其中之一,但是TS有问题,而且会有-。不可否认,@jcalz“breake”是“unsound”的俗语。好像OP在这里指的是什么,所以我就离开了。这不是价值判断,而是对事实的陈述。我并不反对这种行为。这确实意味着编译器有时会拒绝正确的代码或接受错误的代码。尽管如此,它提供的巨大便利远远抵消了这些罕见的情况。
```
type Birds = {
flys: boolean;
layEggs: string;
}
type Fish = {
swim: number;
layEggs: string;
}
type UnionType = Fish | Birds
//Ok to use Object Literal with Object Type
let k1: Birds= {flys:true,layEggs:"yes"}
//Ok to use Object Literal with Object Type
let k2: Fish= {swim:100,layEggs:"of course"}
//BROKEN DO NOT Object Literal with Union Type
let k3: UnionType={flys:true, layEggs:"yeah",swim:22}
//Handle union type with Function Overloading:
declare let bla: UnionType;
bla.layEggs = "yeah"
```
```
interface Birds {
flys: boolean;
layEggs: string;
}
interface Fish {
swim: number;
layEggs: string;
}
type UnionType = Fish | Birds
//Ok to use Object Literal with Object Type
let k1: Birds= {flys:true,layEggs:"yes"}
//Ok to use Object Literal with Object Type
let k2: Fish= {swim:100,layEggs:"of course"}
//BROKEN DO NOT Object Literal with Union Type
let k3: UnionType={flys:true, layEggs:"yeah",swim:22}
//Handle union type with function overloading:
declare let bla: UnionType;
bla.layEggs = "yeah"
```