typescript - 将不正确的变量类型传递给函数不会发出类型错误

标签 typescript

你能解释一下为什么当我将不正确的变量类型传递给函数时 ts 没有发出类型错误吗?

export class CreateCategoryDto implements Omit<Category, 'id' | 'children' | 'parent'> {
  name: string;

  parentId: number;
}

export async function createCategory(dto: CreateCategoryDto) {
  return getRepository(Category).save(dto);
}

const data = { id: 555, name: 'sdfsdf', parentId: 55 };
ctx.body = {
    data1: await createCategory(data), // not emit
    data: await createCategory({ id: 555, name: 'sdfsdf', parentId: 55 }), // emit that params must be without id
  };

最佳答案

这与 excess property checking 有关和 object literal freshness .

您可能会问什么时候对象字面量被认为是新鲜的?

当 Typescript 为您推断其类型并且既没有类型断言也没有将对象文字分配给变量时,对象文字被认为是新鲜的。

// using type assertion, this works
data: await createCategory({ id: 555, name: 'sdfsdf', parentId: 55 } as CreateCategoryDto)

在第一种情况下,您将其分配给了一个变量,因此新鲜度消失了并且没有多余的属性检查。

const data = { id: 555, name: 'sdfsdf', parentId: 55 }; // you assigned it to a variable

data1: await createCategory(data)

但是,在第二种情况下,您直接将对象字面量传递给了函数,而没有先将其分配给变量,因此 Typescript 推断出它的类型:对象字面量是新鲜的。

data: await createCategory({ id: 555, name: 'sdfsdf', parentId: 55 }) // this object is fresh

在这种情况下,我们称之为过度属性检查,其工作方式如下:当您尝试将新的对象字面量类型 T 分配给另一个类型 U,并且 T 具有 U 中不存在的属性时,Typescript提示。这对于检测拼写错误很有用。

引用文档:

[...] TypeScript takes the stance that there’s probably a bug in this code. Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments. If an object literal has any properties that the “target type” doesn’t have, you’ll get an error [...]

这也会产生一个错误:

var categoryDto: CreateCategoryDto = { id: 555, name: 'sdfsdf', parentId: 55 }

而这不是:

var categoryDto = { id: 555, name: 'sdfsdf', parentId: 55 }
var test: CreateCategoryDto = categoryDto

对象类型在其成员中是协变的(您需要 T 或 T 的子类型),额外的属性无关紧要。这可能会导致不安全的行为,但作者希望在易用性和安全性之间取得平衡。在这里,由于对象字面量是新鲜的,因此涉及过多的属性检查。

关于typescript - 将不正确的变量类型传递给函数不会发出类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59124579/

相关文章:

arrays - 如何在 Typescript 4.0.3 中正确扩展数组原型(prototype)?

javascript - MomentJs:如何在 Typescript 中将字符串转换为日期?

javascript - Angular 5 httpClient 版本的代码

typescript :从通用接口(interface)中省略属性

reactjs - 尽管 TypeScript 编译器出现错误,为什么我的 React Native 应用程序仍能成功构建?

angular - 模拟类以使用 Typescript 和 Jest 进行测试

typescript - 如何正确处理 Vuejs 中异步事件监听器中的拒绝错误?

visual-studio-2013 - typescript 1.4 : Wrong syntax highlighting in Visual Studio

javascript - 是否可以定义一个包含对象的对象?

visual-studio-2012 - 如果 Typescript 位于子文件夹中,它不会编译?