Javascript 如何创建允许通过任何字符串进行查询的类型安全对象
我想创建一个object+getter函数,它将返回已知的值类型(如果keyJavascript 如何创建允许通过任何字符串进行查询的类型安全对象,javascript,typescript,typescript-typings,type-safety,typescript-types,Javascript,Typescript,Typescript Typings,Type Safety,Typescript Types,我想创建一个object+getter函数,它将返回已知的值类型(如果key扩展了keyof typeof obj),或者如果我们不知道键是否在对象中,则返回值类型或未定义。不知怎的,是这样的: const obj = { a: 1, b: 2, c: 3 } const a = obj.a // typeof a = number const b = obj['b'] // typeof b = number let key: string = 'anything' cons
扩展了keyof typeof obj
),或者如果我们不知道键是否在对象中,则返回值类型或未定义。不知怎的,是这样的:
const obj = {
a: 1,
b: 2,
c: 3
}
const a = obj.a
// typeof a = number
const b = obj['b']
// typeof b = number
let key: string = 'anything'
const d = obj[key]
// typeof d = number | undefined
if (d) {
// typeof d = number
} else {
// typeof d = undefined
}
但实际上发生的是
let key: string = 'anything'
const d = obj[key]
// TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: number; b: number; c: number; }'. No index signature with a parameter of type 'string' was found on type '{ a: number; b: number; c: number; }'.
I've been trying to create a `get` function which would work this way, but can't get it to work. The result type is always either `any` or `unknown`.
我说对了吗
constobj:Record={…};
常量getter=(键:string):string=>{
if(输入obj)返回obj的类型[输入];
返回未定义;
}
在我看来,TypeScript对这种事情有点不满意。然而,我认为通常的方法是编写一个类型保护。类似下面的东西。isObjKey显式检查实际JavaScript对象是否包含键(obj[key]!==undefined
),并在函数返回true时告诉TypeScript类型(key是keyof typeof obj
)。现在,如果我们使用它进行测试,当您执行obj[key]时,TypeScript知道它在“if”的第一个分支中有一个数字,我想这就是您所要求的。令人不满意的是,我们不得不编写一个新的、困难的函数来做一些琐碎的事情,我们检索了obj[key]两次,只是为了在一个常量对象上获得类型安全性
const obj = {
a: 1,
b: 2,
c: 3
};
let key: string = Math.random() < 0.5 ? 'a' : 'anything';
function isObjKey(key: string): key is keyof typeof obj {
return obj.hasOwnProperty(key);
}
if (isObjKey(key)) {
const d = obj[key];
// d is a number here as far as TypeScript is concerned
console.log(d);
}
else {
// key isn't a valid key of obj, there's no need for another obj[key] access
// (but if you do it's type any, not undefined)
console.log('undefined');
}
我们怎么可能不知道键是否存在于常量对象中?这不适用于--strictNullChecks
,请参阅。如果没有--strictNullChecks
就没有未定义的
类型需要担心,但是这样问题就不会要求类型编号|未定义的
。我不确定这怎么会不令人满意,因为在您的示例中,键绝对可能不是obj的键。任何好的代码都应该检查它。如果“任何事情”是关键,它该怎么办?这不是钥匙谢谢!你的第一个例子我差点就明白了。现在的问题是,除了值的实际类型之外,typescript还说它可以是未定义的
。我知道,实际上,对象可能在运行时发生了更改,但有没有办法告诉TS它不能是未定义的?(如果使用Object.freeze定义,我们知道它无法更改)首先,我意识到如果打开nomplicitany,我的答案就不起作用,我对它进行了编辑以解决这个问题。我已经替换了obj[key]!==未定义的
带有obj.hasOwnProperty(key)
但我不认为这是你的问题?然而,我不明白你的问题是什么:你是说d在“if”语句中显示为“number | undefined”(我在这里写了“d是一个数字”)?因为那不是我看到的。问题具体在哪里(使用哪个变量?)?
const d = obj[key as keyof typeof obj];
if (d) {
// TypeScript thinks d is a number
console.log(d);
} else {
// TypeScript still thinks d is a number, but it probably doesn't matter!
console.log('undefined');
}