首页 > 解决方案 > 为什么在这种情况下 TypeScript 会推断出错误的类型?

问题描述

我有以下代码,打字稿推断变量的类型d是 a string,但实际上它应该是 a string | number。我知道这是由于 typescript 的一项功能(称为由于分配而导致类型缩小)造成的。但它可能会变得非常不安全(正如以下代码所暗示的那样)。如何选择退出这种行为?

interface Z {
    name: string | number;
}

const f = (z: Z) => {
    z.name = 200;
};

let z: Z = {
    name: 2,
};

z.name = '2';

f(z);

const d = z.name;

编辑:似乎解决这个问题的一种方法是让一些 linter 参数不可修改(但这非常有限制)。

标签: javascripttypescripttypes

解决方案


我不确定这种行为是“可配置的”。

你的f函数正在改变它的参数的属性类型,z我猜编译器没有检查那么深。

如果您希望输入正确,您将不得不告诉 TypeScript 您正在对变量执行某些操作。

这会起作用:

interface Z { name: string | number; }

const f = (z: Z) => {
    z.name = 200;
    return z;
};

let z: Z = { name: 2 };

z.name = '2';

z = f(z);

const d = z.name;

替换z为返回值使 TS “持久化” 中发生的类型更改f(z)

或这个:

interface Zbase { name: any }
interface Z       extends Zbase { name: string | number; }
interface Znumber extends Zbase { name: number; }
interface Zstring extends Zbase { name: string; }

const f = (z: Z) => { z.name = 200; };
let z: Z = { name: 2 };

z.name = '2';

f(z);

const d = (z as Znumber).name;

现在,这些都不是很漂亮,但我通常认为这是我在编写 TS 时做错了什么的标志:

为什么 aname可以是 anumber或 a string
我还能如何接近<requirement>,以便我可以正确输入我的属性?


推荐阅读