接口在用作函数的返回类型时允许额外的属性 [英] Interface is allowing extra property when it is used as return type of a function

查看:24
本文介绍了接口在用作函数的返回类型时允许额外的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当一个接口通过类型被分配为函数的返回时,它似乎接受额外的属性.

An inteface seems to accept extra property(ies) when it is assigned as a return of a function via a type.

例如,如果我有一个名为 MyInterface 的空接口,一个函数类型:type MyFunction = () =>MyInterface; 和一个函数 const myFunction: MyFunction = () =>({ foo: 'bar' }) 它不会为 foo 属性抛出任何错误.

For example if I have an empty interface named MyInterface, a type for a function : type MyFunction = () => MyInterface; and a function const myFunction: MyFunction = () => ({ foo: 'bar' }) it does not throw any error for the foo property.

这里有一些例子:

// No 'age' property
interface Human {
  name: string;
}

const human: Human = {
  name: '',
  age: 0 // Error
}

type HumanCreator = (name: Human['name'], age: number) => Human;

const humanCreator: HumanCreator = (name, age) => ({
  name,
  age // No error. Why?
});

const humanCreatorr: HumanCreator = (name, age): Human => ({
  name,
  age // Error
});

const humanCreatorrr = (): Human => ({
  name: '',
  age: 0 // Error
});

为什么当我用 HumanCreator 输入变量 humanCreator 时,它并不关心我是否向返回的对象添加了额外的属性?

Why when I type the variable humanCreator with HumanCreator it does not care if I add extra property(ies) to the returned object?

推荐答案

当一个接口通过类型被分配为函数的返回时,它似乎接受额外的属性.

An inteface seems to accept extra property(ies) when it is assigned as a return of a function via a type.

一般来说,TypeScript 使用结构类型,因此将具有附加属性的对象分配给 Human 接口是完全可以的.

In general, TypeScript uses structural typing, so it is perfectly fine to assign an object with additional properties to a Human interface.

const lui = {
  name: "Lui",
  age: 40
}

const human: Human = lui // works, 

你可以将lui赋值给Human类型的变量human,因为typeof lui是一个子类型因此具有相同/兼容的属性成员.

You can assign lui to variable human with type Human, because typeof lui is a sub-type and therefore has the same/compatible property members.

此规则的一个例外是过多的属性检查 用于新创建的对象文字",旨在作为开发人员的帮助并禁止添加额外的属性.这里的一般想法是,当您定义没有其他间接方式(访问变量等以获取该对象值)的直接对象字面量时,您完全知道自己想要什么属性.

An exception to this rule are excess property checks for "freshly created object literals", that are intended as developer aid and prohibit extra properties to be added. The general thought here is, that you exactly know what properties you want, when you define a direct object literal with no other indirection (access of variables etc. to get that object value).

多余的属性检查需要在处理新对象字面量的变量、属性或函数处紧随其后的显式类型注释才能工作.否则对象文字类型不再算作新鲜"(它的类型是 扩大).让我们检查您的示例来说明这个概念.

Excess property checks require an immediately following explicit type annotation at the variable, property or function dealing with the fresh object literal in order to work. Otherwise the object literal type doesn't count as "fresh" anymore (its type is widened). Let's check your examples to illustrate the concept.

const humanCreator: HumanCreator = (name, age) => ({
  name,
  age // No error. Why?
});

您可以将其视为将类型兼容函数分配给类型为 HumanCreator 的变量.编译器查看函数表达式 (name, age) =>;({ name, age }),推断参数类型并确保其返回类型与变量类型兼容.事实上 - {name: string;age:number} 返回类型可分配给 Human(结构类型).

You can see this as an assignment of a type compatible function to the variable with type HumanCreator. The compiler looks at the function expression (name, age) => ({ name, age }), infers parameter types and makes sure that its return type is compatible to the variable type. And indeed - {name: string; age:number} return type is assignable to Human (structural typing).

const humanCreatorr: HumanCreator = (name, age): Human => ({
  name,
  age // Error
});

const humanCreatorrr = (): Human => ({
  name: '',
  age: 0 // Error
});

这些情况不同,因为您立即使用 Human 返回类型注释函数.编译器所需的返回类型没有类型推断.tl;dr 要启用多余的属性检查,请尽可能为您的对象字面量添加显式类型的注释.

These cases are different, as you immediately annotate the functions with Human return type. There is no type inference for the return type necessary for the compiler. tl;dr To enable excess property checks, annotate an explicit type for your object literal as close as possible.

进一步链接

这篇关于接口在用作函数的返回类型时允许额外的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆