为什么子类型需要在用作函数参数之前分配给变量? [英] Why do subtypes need to be assigned to a variable before being used as a function argument?

查看:27
本文介绍了为什么子类型需要在用作函数参数之前分配给变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习子类型,想知道为什么这里给出一个例子 https://www.typescriptlang.org/docs/handbook/type-compatibility.html 可以编译,但是当我将子类型作为参数直接传递给函数时,它不会编译.

I'm learning about subtypes and am wondering why an example given here https://www.typescriptlang.org/docs/handbook/type-compatibility.html compiles, but when I pass the subtype directly as an argument to a function, it does not compile.

这是来自 typescriptlang.org 的原始代码

Here's the original code from 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 的版本失败了.

That compiles fine. But this version, where the subtype is not assigned to y, fails.

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; 类型的参数位置:字符串;}' 不能分配给'Named' 类型的参数.对象字面量只能指定已知的属性,并且在Named"类型中不存在location".

Argument of type '{ name: string; location: string; }' is not assignable to parameter of type 'Named'. Object literal may only specify known properties, and 'location' does not exist in type 'Named'.

为什么子类型 { name: "Alice", location: "Seattle" } 必须先赋值给一个变量?

Why is it that the subtype { name: "Alice", location: "Seattle" } has to be assigned to a variable first?

推荐答案

这是因为当您使用新鲜"时对象字面量(意味着尚未分配给变量的对象)在需要特定类型的地方,添加类型中未提及的属性通常是一个错误.因此,这通过 过多的属性检查.它是少数几个将类型视为封闭"的地方之一.或精确",而不是开放".

It's because when you use a "fresh" object literal (meaning one that hasn't been assigned to a variable yet) in a place that expects a particular type, it's often an error to add properties not mentioned in the type. So this is flagged as an error via excess property checking. It's one of the few places where a type is treated as "closed" or "exact" as opposed to "open".

在您不打算进行过多的财产检查的情况下,有一些解决方法.一种是在类型中添加索引签名n 参数,以便所有额外的属性都可以接受:

There are workarounds in the case where you don't mean for excess property checks to happen. One is to add an index signature to the type of the n parameter so that all extra properties are acceptable:

function greet(n: Named & { [x: string]: unknown }) {
  console.log("Hello, " + n.name);
}
greet({ name: "Alice", location: "Seattle" }); // okay

或者,如果您通常想要进行此类检查,但只想使用该特定对象文字调用 greet(),则可以使用 类型断言以避免中间变量:

Or, if you usually want such checking but just want to call greet() with that particular object literal, you can use a type assertion to avoid intermediate variables:

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

这取决于你.好的,希望有帮助;祝你好运!

It's up to you. Okay, hope that helps; good luck!

这篇关于为什么子类型需要在用作函数参数之前分配给变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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