【发布时间】:2021-06-21 06:49:51
【问题描述】:
我最近遇到了一个运行时 TypeError,我认为应该可以在使用 TypeScript 的编译期间捕获一些东西。代码如下:
type MyObject = Record<string, Record<string, string>>;
function getParameters(): MyObject
{
return {
test: {
test: "val",
}
};
}
const params = getParameters();
const v = params.Section.Val; // TypeError: params.Section is undefined
由于MyObject 是一个对象,其中键为strings,TypeScript 似乎认为任何string 都可以用作键,并将产生Record<string, string> 值。这通常是不正确的,因为对象上通常有有限数量的键,除非您在对象上定义一个 getter,它可以为任何其他作为键给出的字符串返回一个字符串。
所以我尝试使用type MyObject = Partial<Record<string, Record<string, string>>>。使用这种类型会捕获上述错误,但是当您尝试迭代对象时会引入问题:
type MyObject = Partial<Record<string, Record<string, string>>>;
function getParameters(): MyObject
{
return {
test: {
test: "val",
}
};
}
const params = getParameters();
Object.values(params).filter(v => v.Value); // v: Object is possibly undefined
上面的错误永远不会在运行时发生,因为如果属性存在于params,我知道它将是Record<string, string>。但我不知道如何使用类型系统来表达。
所以我的问题是:如何为对象定义一个类型
- 只有字符串键,并且
- 没有为所有字符串定义了属性,并且
- 如果定义了一个属性,我知道对应值的类型是
Record<string, string>?
编辑:我知道可以指定类型中的所有键(如Record<"keya"|"keyb", string>),但这不是我想要的,因为我事先不知道所有键。我想要的是一种我们可以称之为PartialRecord的类型,如果params: PartialRecord<string, T>,那么params.SOMEKEY的类型为T | undefined(因为密钥SOMEKEY可能不存在,这意味着访问它将返回undefined)但是Object.values(params) 应该有T[] 类型,因为我们知道Object.values 只会返回存在的值,并且它们都是T 类型。
【问题讨论】:
标签: typescript