函数返回值中的部分类型不如预期的严格

时间:2018-04-27 15:16:31

标签: javascript typescript

我试图对函数(A)进行严格的类型检查,将参数传递给另一个函数。 A的返回值必须是给定接口的Partial

所以考虑以下界面:

interface IUser {
    name: string;
    age: number;
}

如果函数的返回值不是此接口的Partial,我想要的是TypeScript给我一个错误

function check(f: () => Partial<IUser>) {
    return f; // implementation of this function is pointless, only the type checking here interests me
}

当返回一个不包含接口键的对象时,TS会给出错误,这是预期的。
但是当返回的对象上至少有一个IUser键时,不再有错误,那就是意外

check(() => ({ foo: 'bar' })); // GOOD - Type '{ foo: 'bar' }' has no properties in common with type 'Partial<IUser>'.

check(() => ({ foo: 'bar', name: 'Dar' })); // BAD - no error

我无法理解为什么TS没有抛出错误,因为当尝试使用额外属性创建类型为Partial<IUser>的对象时,会抛出错误。

const o: Partial<IUser> = {
    name: 'Dar',
    foo: 'bar',
}; // Object literal may only specify known properties, and 'foo' does not exist in type 'Partial<IUser>'.

在使用像这样的回调时,有没有办法让TS抛出错误?

注意:使用TypeScript 2.8.1进行测试

1 个答案:

答案 0 :(得分:2)

虽然我不确定我是否有确切答案,但我认为这是TypeScript固有的行为,而不是您使用Partials的方式。

Partials are defined in the TypeScript规范如下:

type Partial<T> = {
    [P in keyof T]?: T[P];
}

作为一项完整性检查,我使用明确的Weak Type (See breaking change in TypeScript 2.4)代替Partial和I got the same result重写了您的代码。

我找到了this issue on the TypeScript repo: Function interface doesn't type check return value for extra keys。看起来该类型不会自动从check签名中推断出来。看起来它与对象文字的新鲜度有关,并且问题没有得到解决(正如您从该问题讨论中看到的那样)。

好消息是看起来有一种方法可以手动强制执行。为此,您可以包含以下内容:

check((): Partial<IUser> => ({ foo: 'bar', name: 'Dar' }));

现在,这将在底部创建类似的错误:Object literal may only specify known properties, and 'foo' does not exist in type 'Partial<IUser>'。您可以在playground here

中查看