防止typescript允许未定义的返回

防止typescript允许未定义的返回,typescript,Typescript,我已经启用了所有我希望启用的严格标志,因此当Typescript接受以下代码时,我感到困惑: export class Test { private records: { [id: string]: number }; constructor() { this.records = { "hello": 1, "world": 3 } } public get(

我已经启用了所有我希望启用的严格标志,因此当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
属性并不总是返回一个数字:当传递函数时,除了
“hello”
“world”
之外,它还将返回
未定义的
。是否有一个标志可以捕获此函数并要求其返回类型为
number | undefined
,这是正确的返回类型

我已经在使用
noImplicitAny
stricknullchecks
。当然有办法做到这一点,因为我有一个函数,它声明返回一个
数字
返回
未定义

试试这个:

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

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

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

根据jonrsharpe的评论,我最终找到了答案。据我所知,答案是:

interface Wha { 
    foo: number;
    bar: number;
    [id: string]: number;
};
总是不正确的,因为类型系统将其视为将每个
id
映射到定义的数字的对象,并且此类对象永远不可能存在。(正如lilezek在评论中指出的那样,您可能创建的每个对象都将始终具有不映射到数字的字符串。)

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

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

因为它错误地认为
Wha
对象中的每个
字符串
索引都映射到定义的
数字
,Typescript将
r.notafield
r.fnord
r[“ha”]
视为具有类型
数字
。因此,它将愉快地进行,就好像所有这些事情都不可能是未定义的一样。但是它们都是未定义的!避免这种情况就是为什么我想将Typescript与
--strictNullChecks
结合使用的原因。首先,您的类型表示该对象上的任何字符串键都将返回一个数字。如果只能访问特定的已知属性,请使用更具体的类型。@jonrsharpe-如果是这样,则构造函数中应该有一个类型错误,而没有。我知道我可以在这个实例中使用更具体的接口类型,但我从中得到的示例也有一个方法
集(id:string,n:number):void
。从根本上说,问题是因为
记录的类型是错误的。正如您所说,如果缺少密钥,您将无法定义它,因此它应该是
[id:string]:number | undefined
。然后您确实会在该方法上得到相应的警告。我不知道你为什么认为构造函数中应该有类型错误。另请参阅此问题:@jornsharpe Rob Simmons有一个很好的观点,即对象不能将所有可能的键都包含为数字。所以,对于某些键,它应该是未定义的。@lilezek是的,我理解他们的意思,但这不是索引签名的工作方式。