防止打字稿允许未定义的返回

时间:2017-10-13 21:29:33

标签: typescript

我已经获得了所有可以打开的严格标志,所以当Typescript接受以下代码时我很困惑:

export class Test {
    private records: {
        [id: string]: number
    };
    constructor() {
        this.records = {
            "hello": 1,
            "world": 3
        }
    }

    public get(id: string): number {
        return this.records[id];
    } 
}

get属性显然 not 总是返回一个数字:当函数传递undefined和{{1}之外的任何内容时,它将返回"hello" }。是否有一个标志会捕获此函数并要求其返回类型为"world",这是正确的返回类型?

我已经使用number | undefinednoImplicitAny了。当然有一些方法可以做到这一点,因为我有一个声称返回strictNullChecks返回number的函数!

2 个答案:

答案 0 :(得分:1)

根据jonrsharpe的评论,我最终找到了this thread。我理解的答案就是这种类型:

interface Wha { 
    foo: number;
    bar: number;
    [id: string]: number;
};

始终不正确,因为类型系统会将其视为将每个id 映射到定义的数字的对象,并且永远不存在这样的对象。 (正如lilezek在评论中指出的那样,您可能创建的每个对象都将始终具有不映射到数字的字符串。)

Typescript非常乐意为此对象提供Wha类型:

let r: Wha = { foo: 4, bar: 7, baz: 33 };

因为它错误地认为string对象中的每个Wha索引都映射到定义的number,因此Typescript会处理r.notafieldr.fnord和{ {1}}类型为r["ha"]。因此,它将很乐意继续进行,好像所有这些事情都不能可能未定义。但他们都是number!避免这种情况是我想在第一时间使用带有undefined的Typescript的原因

如果你想避免让一群--strictNullChecks东西围绕着一个假装完全定义undefined的类型搜索器,那么唯一的选择就是这样:

number

这会导致各种各样的问题,因为这意味着您可以在映射到undefined的数组中拥有有效的键,其中最初的含义是,如果interface Wha { foo: number; bar: number; [id: string]: number | undefined; }; k中的一个键,然后Object.keys(r)r[k]。所以这里没有好的选择。

也许这里的教训是我应该使用ES6 Maps而不是可索引类型,因为可转换类型在没有警告的情况下对你说谎。

答案 1 :(得分:0)

试试这个:

^(\d*[\d.]*?)\.?0*$

或者这个:

public get(id: string): number | undefined {
    return this.records[id];
} 

其中一个应显式返回undefined作为可能的类型。