Typescript 无法检查函数返回类型的嵌套对象
Posted
技术标签:
【中文标题】Typescript 无法检查函数返回类型的嵌套对象【英文标题】:Typescript fails to check nested object on function return type 【发布时间】: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 并没有显示任何错误。
是的,我把A
和B
弄糊涂了。
我的错。它可以以更清晰的方式命名哈哈
【参考方案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 文档正在经历重大改写,链接页面被列为“已弃用”,并带有“新页面”的新增内容,但新页面尚未描述过多的财产检查。希望尽快解决。
【讨论】:
啊,明白了!非常感谢您为我指出“多余的财产检查”。我不知道这一点。另外,感谢您提出的解决方案。非常有帮助。谢谢!!以上是关于Typescript 无法检查函数返回类型的嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章