接口通过类型分配为函数的返回值时,它似乎会接受其他属性。
例如,如果我有一个名为MyInterface
的空接口,一个函数的类型:type MyFunction = () => MyInterface;
和一个函数const myFunction: MyFunction = () => ({ foo: 'bar' })
,则对于foo
不会引发任何错误属性。
以下是一些示例:
// 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
时,我不在乎是否向返回的对象添加了额外的属性?
答案 0 :(得分:2)
接口通过类型分配为函数的返回值时,它似乎会接受其他属性。
通常,TypeScript使用structural typing,因此可以将具有附加属性的对象分配给Human
接口。
const lui = {
name: "Lui",
age: 40
}
const human: Human = lui // works,
您可以将lui
分配给类型为{{1}的变量human
,因为Human
是子类型,因此具有相同/兼容的属性成员。
此规则的例外是excess property checks的“新创建的对象文字”,旨在作为开发人员的帮助,并禁止添加其他属性。通常的想法是,当您定义一个没有其他间接性的直接对象文字(访问变量等以获取该对象值)时,您便完全知道所需的属性。
多余的属性检查要求在紧跟新对象文字的变量,属性或函数后紧跟显式类型注释,以便起作用。否则,对象文字类型将不再视为“新鲜”(其类型为widened)。让我们检查您的示例以说明概念。
typeof lui
您可以看到这是类型兼容函数对类型为const humanCreator: HumanCreator = (name, age) => ({
name,
age // No error. Why?
});
的变量的赋值。编译器查看函数表达式HumanCreator
,推断参数类型,并确保其返回类型与变量类型兼容。确实-(name, age) => ({ name, age })
返回类型可分配给{name: string; age:number}
(结构化类型)。
Human
这些情况有所不同,因为您立即使用const humanCreatorr: HumanCreator = (name, age): Human => ({
name,
age // Error
});
const humanCreatorrr = (): Human => ({
name: '',
age: 0 // Error
});
返回类型对函数进行注释。编译器不需要返回类型的类型推断。 tl; dr 要启用多余的属性检查,请为对象文字的显式类型尽可能靠近注释。
其他链接