【问题标题】:Typescript fails to check nested object on function return typeTypescript 无法检查函数返回类型的嵌套对象
【发布时间】:2021-07-16 12:16:55
【问题描述】:

Typescript 无法检查返回类型是否为嵌套对象。考虑下面的代码,即使函数 A 中的结果变量显然与输出类型不匹配,Typescript 也不会发出错误。

interface Input {
  a: string;
  b: number;
}

interface Output {
  c: Omit<Input, 'a'>;
  d: string;
}

function A(input: Input): Output {
  const result = { c: {a: 'aaa', b: 3}, d: 'okay' };

  // Expect to have an error since the result is not matched to Output
  // but there's not errors
  return result;
}

function B(input: Input): Output {
  const result = "{ c: {a: 'aaa', b: 3}, d: 'okay' }";

  // Work as expected
  return result;
}

// But access a property will give us error. 
const test = A({ a: 'a', b: 3 });
test.c.a

Playground here.

知道为什么会这样吗?

如果我们明确告诉 Typescript const result: Output = ...,它会给我们错误。但我不确定这是否是一个好习惯。还有其他方法可以使其按预期工作吗?

【问题讨论】:

  • 为什么const result = "{ c: {a: 'aaa', b: 3}, d: 'okay' }"; 中的值有引号? (我敢肯定你一秒钟前没有,是吗……?)
  • 这里是测试typescript是否进行类型检查。在函数 A 中,我返回一个对象,在函数 B 中,我返回一个字符串。 Typescript 确实在函数 B 中显示错误,因为 String 与输出类型不匹配。但是当涉及到一个对象时,Typescript 并没有显示任何错误。
  • 是的,我把AB 弄糊涂了。
  • 我的错。它可以以更清晰的方式命名哈哈

标签: typescript typechecking


【解决方案1】:

知道为什么会这样吗?

如果我们明确告诉 Typescript const result: Output = ...,它会给我们错误....

TypeScript 对对象 literals 应用比对其他表达式(包括变量引用)更严格的类型检查。在这种情况下,当您显式为 result 提供类型时,“更严格”的部分是 excess property check。¹这是一个务实的检查,因为通常这是一个程序员错误,但在一般 case 多余的属性是可以的(因为对象的形状仍然匹配目标类型,它只是一个子类型,因为它有更多的属性)。

如果你直接返回,你也会得到错误:

function A(input: Input): Output {
    return { c: {a: 'aaa', b: 3}, d: 'okay' };
}

虽然(主观上)我通常更喜欢您的原始代码,因为它更容易调试。

这主要是风格问题,但如果可能,我会通过将其作为一般做法来解决问题:

function A(input: Input) {
//                      ^−−−− No return type annotation
    const result: Output = { c: {a: 'aaa', b: 3}, d: 'okay' };
//                ^−−−−−−−−−− Explicit type

    return result; // <−−−−−− TypeScript infers return type
}

请注意,函数的返回类型仍然是 Output,只是 TypeScript 从 return 推断出来的,而不是我们在两个地方明确指定它。

Playground link


¹ 当我在 2021 年 4 月写这篇文章时,TypeScript 文档正在经历重大改写,链接页面被列为“已弃用”,并带有“新页面”的新增内容,但新页面尚未描述过多的财产检查。希望尽快解决。

【讨论】:

  • 啊,明白了!非常感谢您为我指出“多余的财产检查”。我不知道这一点。另外,感谢您提出的解决方案。非常有帮助。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2021-05-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多