Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何创建允许通过任何字符串进行查询的类型安全对象_Javascript_Typescript_Typescript Typings_Type Safety_Typescript Types - Fatal编程技术网

Javascript 如何创建允许通过任何字符串进行查询的类型安全对象

Javascript 如何创建允许通过任何字符串进行查询的类型安全对象,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

我想创建一个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'
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');
}