为什么Typescript允许我用错误的接口类型调用函数
考虑以下情况。 使用类型为1的参数调用func时,Typescript没有报告错误-为什么为什么Typescript允许我用错误的接口类型调用函数,typescript,Typescript,考虑以下情况。 使用类型为1的参数调用func时,Typescript没有报告错误-为什么 export interface One { common?: string one?: string; } export interface Two { common?: string two?: string; } export function func(arg: Two) { // do something! } const one: One =
export interface One {
common?: string
one?: string;
}
export interface Two {
common?: string
two?: string;
}
export function func(arg: Two) {
// do something!
}
const one: One = {
common: 'common',
one: 'One'
};
const two: Two = {
common: 'common',
two: 'Two'
}
func(one);
根本问题是
One
和Two
是您定义的相互兼容的类型
我不知道是否有更为规范的文档来源,但声明目标对象类型t的所有属性都与源类型s的类似属性兼容,那么类型s的值可分配给类型t的变量
在您的情况下,One
可分配给Two
,因为:
的属性Two
是可选的common
值,字符串
的属性也是可选的;及One
的属性Two
是可选的Two
值,字符串
没有此名称的属性One
Two
可分配给One
:
的属性One
是可选的common
值,字符串
也是可选的;及Two
的属性One
是可选的One
值,string
没有此名称的属性Two
One
或Two
)分配任何值,则会出现问题,除非它们至少共享一个属性。这可以防止像{a?:string}
这样疯狂的东西与{b?:number}
兼容,但是在您的例子中,公共
同时存在于One
或Two
中,这一事实禁用了弱类型检查
我的建议是,如果您有两个意外兼容的类型,您可以通过将有问题的属性键显式地添加到其他类型,作为类型
never
或undefined
的可选属性来区分它们:
export interface One {
common?: string
one?: string;
two?: undefined;
}
export interface Two {
common?: string
one?: undefined;
two?: string;
}
这与您打算分配给这些类型的内容没有太大区别:
const one: One = {
common: 'common',
one: 'One'
}; // still okay
const two: Two = {
common: 'common',
two: 'Two'
} // still okay
但是现在编译器认为One
和Two
是不兼容的:
func(one); // error!
// ~~~ <-- Types of property 'one' are incompatible.
func(一);//错误!
//~~~你能在打字游戏场试试这个吗?此外,如果您的接口没有必需的属性,则通常是警告或错误。您的接口实际上是否只有可选属性?是否在typescript中尝试过,没有错误或警告:(因此,如果您将属性更改为“全部必需”。或者即使在每个接口上只设置“公共”可选项,它也会出错。TS是结构类型,One
和Two
是相同的结构,因此彼此兼容并可分配。@AlexanderStaroselsky它实际上比这更有趣……谢谢您的支持。)详细解释如下,但我们使用YAML中的openapi生成器生成typescript接口,因此添加任何额外属性都是不可行的:(即使您以编程方式生成接口,您也可以始终在via中添加额外属性。或者您也可以修改yaml以在其中添加属性。或者您可以不使用生成的接口,而创建新接口,并使用添加的属性对其进行扩展。等等。重点是:如果您正在编写任何TS代码,您可以可能会做些什么来解决这个问题。再次祝你好运!