我已经打开了我期望的所有严格标志,所以当 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
属性显然不总是返回一个数字:它会返回 undefined
当函数被传递除了 之外的任何东西时”你好”
和 “世界”
。是否有一个标志可以捕获此函数并要求其返回类型为 number | undefined
,哪个是正确的返回类型?
我已经在使用 noImplicitAny
和 strictNullChecks
。当然有一些方法可以做到这一点,因为我有一个函数声称返回 number
返回 undefined
!
最佳答案
根据 jonrsharpe 的评论,我最终找到了 this thread .据我了解,答案是这种类型:
interface Wha {
foo: number;
bar: number;
[id: string]: number;
};
总是不正确,因为类型系统将其视为将每个id
映射到定义的对象number,这样的对象永远不存在。 (正如 lilezek 在评论中指出的那样,您可能创建的每个对象都将始终包含未映射到数字的字符串。)
Typescript 非常乐意为该对象赋予 Wha
类型:
let r: Wha = { foo: 4, bar: 7, baz: 33 };
因为它错误地认为 Wha
对象中的每个 string
索引都映射到定义的 number
,Typescript 将对待 r。 notafield
、r.fnord
和 r["ha"]
具有 number
类型。因此,它会愉快地继续,就好像所有这些事情都可能是未定义的一样。但它们都是 undefined
!避免这种情况就是为什么我想首先将 Typescript 与 --strictNullChecks
一起使用😐
如果你想避免一堆 undefined
东西在类型检查器周围压缩,假装是一个完全定义的 number
,唯一的选择是:
interface Wha {
foo: number;
bar: number;
[id: string]: number | undefined;
};
这会导致各种问题,因为这意味着您可以在数组中拥有映射到未定义的有效键,而您最初的意思是这样的,如果k
是Object.keys(r)
中的一个key,那么r[k]
就是一个number
。所以这里没有好的选择。
也许这里的教训是我应该使用 ES6 Maps而不是可索引类型,因为可索引类型会在没有警告的情况下对您撒谎。
关于typescript - 防止 typescript 允许未定义的返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46738279/