为什么TS中允许使用此代码?

interface IFoo {
    foo(a: string | number): void
}

class Bar implements IFoo {
    foo(a: string) { }
}

我认为编译器应该抛出错误,因为Bar的参数a: stringIFooa: string | number窄/不可替换.

推荐答案

这是刻意的设计和故意的行为,由于Function Parameter Bivariance.

比较函数参数的类型时,如果源参数之一可分配给目标参数,则分配成功,反之亦然.[.]

https://www.typescriptlang.org/docs/handbook/type-compatibility.html#function-parameter-bivariance

从本质上讲,这意味着函数类型是以两种方式进行判断的.foo的类实现不仅可以赋值给IFoo中的声明,如果它的类型大于narrow,而且如果它是wider,也可以赋值给IFoo中的声明.仅当接口声明和类类型实现都不可相互赋值时,才会发生类型错误.

interface IFoo {
  foo(a: string | number): void;
}

class Bar implements IFoo {
  foo(a: string) {}
}

class Baz implements IFoo {
  foo(a: string | number | boolean) {}
}

class Invalid implements IFoo {
  foo(a: string | boolean) {}
//~~~ Property 'foo' in type 'Invalid' is not assignable...
}

您可以通过启用--strictFunctionTypes来防止这种情况. 然而,还有一件重要的事情需要注意.严格参数类型判断仅在将foo声明为arrow function(foo: (a: string | number) => void;)时有效.

在开发此功能的过程中,我们发现了大量本质上不安全的类层次 struct ,包括DOM中的一些.因此,该设置仅适用于使用函数语法编写的函数,而不适用于使用方法语法编写的函数.

https://www.typescriptlang.org/tsconfig/#strictFunctionTypes

现在,您将得到预期的参数类型判断:

interface IFoo {
  foo: (a: string | number) => void; // <- !! function syntax
}

class Bar implements IFoo {
  foo(a: string) { }
//~~~ Property 'foo' in type 'Bar' is not assignable...
}

Typescript相关问答推荐

我可以让Typescript根据已区分的联合键缩小对象值类型吗?

如何在另一个if条件中添加if条件

使用FormArray在Angular中添加排序

ReturnType此索引方法与点表示法之间的差异

typescript抱怨值可以是未定义的,尽管类型没有定义

TypeScript实用程序类型—至少需要一个属性的接口,某些指定属性除外

如何访问Content UI的DatePicker/中的sx props of year picker?'<>

Redux—Toolkit查询仅在不为空的情况下添加参数

异步动态生成Playwright测试,显示未找到测试

根据另一个属性的值来推断属性的类型

Angular 17子路由

React router 6(数据路由)使用数据重定向

我在Angular 17中的environment.ts文件中得到了一个属性端点错误

Typescript 中相同类型的不同结果

Typescript,如何在通过属性存在过滤后重新分配类型?

为什么TypeScrip假定{...省略类型,缺少类型,...选取类型,添加&>}为省略类型,缺少类型?

如何将 MUI 主题对象的自定义属性与情感样式组件中的自定义props 一起使用?

如何使用 runInInjectionContext 中的参数测试功能性路由防护

如何为字符串模板文字创建类型保护

如何强制对象数组中的对象属性具有非空字符串值?