Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Typescript允许我用错误的接口类型调用函数_Typescript - Fatal编程技术网

为什么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 =

考虑以下情况。 使用类型为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 = {
    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
    没有此名称的属性
这种兼容性可能令人惊讶。引入了TypeScript 2.4,如果您尝试为所有可选属性类型(如
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代码,您可以可能会做些什么来解决这个问题。再次祝你好运!