Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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_Subtyping - Fatal编程技术网

Typescript 为什么子类型在用作函数参数之前需要分配给变量?

Typescript 为什么子类型在用作函数参数之前需要分配给变量?,typescript,subtyping,Typescript,Subtyping,我正在学习子类型,并且想知道为什么这里给出的示例会编译,但是当我将子类型作为参数直接传递给函数时,它不会编译 这是typescriptlang.org的原始代码 interface Named { name: string; } let x: Named; // y's inferred type is { name: string; location: string; } let y = { name: "Alice", location: "Seattle" }; functi

我正在学习子类型,并且想知道为什么这里给出的示例会编译,但是当我将子类型作为参数直接传递给函数时,它不会编译

这是typescriptlang.org的原始代码

interface Named {
    name: string;
}

let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: "Alice", location: "Seattle" };


function greet(n: Named) {
    console.log("Hello, " + n.name);
}
greet(y); // OK
那很好。但此版本(子类型未指定给y)失败

interface Named {
    name: string;
}

let x: Named;

function greet(n: Named) {
    console.log("Hello, " + n.name);
}
greet({ name: "Alice", location: "Seattle" }); // NOT OK
我得到一个错误:

类型为“{name:string;location:string;}”的参数不能分配给类型为“Named”的参数。Object literal只能指定已知属性,并且“location”在类型“Named”中不存在


为什么子类型{name:“Alice”,location:“Seattle”}必须首先分配给变量?

这是因为当您在需要特定类型的位置使用“fresh”对象文字(表示尚未分配给变量的文字)时,添加类型中未提及的属性通常是错误的。因此,这被标记为错误。它是少数几个将类型视为“封闭”或“开放”的地方之一

如果您不打算进行过多的财产检查,则有一些变通办法。一种是在
n
参数的类型中添加一个参数,以便所有额外的属性都可以接受:

function greet(n: Named & { [x: string]: unknown }) {
  console.log("Hello, " + n.name);
}
greet({ name: "Alice", location: "Seattle" }); // okay
或者,如果您通常希望进行此类检查,但只想使用特定的对象文本调用
greet()
,则可以使用来避免中间变量:

greet({ name: "Alice", location: "Seattle" } as Named); // okay

这取决于你。好吧,希望这会有帮助;祝你好运

它被称为多余属性检查,只有当您为给定类型的参数指定一个新的对象文本时才会触发。Titian Cernicova Dragomir已经给了您答案,但您应该查看官方文档以获得更深入的解释:另外,如果您不想使用变量,还有另一个选项:greet({name:“爱丽丝”,地点:“西雅图”}命名);非常奇怪,将对象分配给另一个变量会绕过检查。您可以阅读详细的工作原理。其目的似乎是捕获额外的属性,而不是以静默方式丢弃。如果您分配给另一个变量,则该变量的推断类型将具有额外的属性。之后,如果您将其传递给一些期待更广泛的类型,他们认为你是有意这样做的。