如何在 Typescript 中执行此操作:当计算的 属性 不存在时使用默认值?

How to do this in Typescript: using the default value when the computed property does not exist?

在javascript中使用Computed 属性时,我可以这样写我的代码

const def_val = {a:"debug",b:"info",c:"warning"};

function work(y) {
    let x = def_val[y] || def_val.a /* if y is not a or b or c */
}

但是我如何在 typescript 中实现它?

const def_val = {a:"debug",b:"info",c:"warning"};

function work(y: string) {
    let x = def_val[y] || def_val.a;
}

我遇到了编译器错误

error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ a: string; b: string; c: string; }'.

No index signature with a parameter of type 'string' was found on type '{ a: string; b: string; c: string; }'.

我搜索了 SO 但我只能找到 这不是我的问题。

现在把我的ts代码改成了这些,但是比起原来的js代码感觉比较繁琐

function work(y: string) {
    let x:string
    if (y!='a' && y!='b' && y!='c') {
        x = def_val.a;
    } else {
        x = def_val[y]
    }
}

----更新----

@captain-yossarian 的回答是解决它的一种方法,例如const def_val: Record<string, string> = { a: "debug", b: "info", c: "warning" };

我发现另一种修复方法是使用 keyof typeof,请在此处查看 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html#keyof-and-lookup-types 以获取更多信息,例如“在 JavaScript 中, 期望 属性 名称作为参数 的 API 是相当普遍的,但到目前为止,还无法表达类型关系发生在这些 API 中。”,这正是我的情况!!

const def_val = {a:"debug",b:"info",c:"warning"};

function work(y:keyof typeof def_val) {
    let x = def_val[y] || def_val.a;

}

我从

那里得到了这个答案

def_val 被打字稿推断为

const def_val: {
    a: string;
    b: string;
    c: string;
}

y 参数有 string 类型

def_val 期望 'a' | 'b' | 'c' 作为键。这意味着打字稿只允许您将这些键与 def_val 一起使用。由于 string 类型比 'a' | 'b' | 'c' 宽得多,您会遇到错误。

y:string 意味着它允许你传递 foo 属性 而 def_val['foo'] 是不安全的,因为 foo 不存在于 def_val.

为了修复它,您应该为 def_val:

提供显式类型
const def_val: Record<string, string> = { a: "debug", b: "info", c: "warning" };

function work(y: string) {
    let x = def_val[y] || def_val.a // ok
}

如果不允许在 def_val 上使用显式类型,您可以提供 def_val 作为 work 的参数:


const def_val = { a: "debug", b: "info", c: "warning" };

function work<Def extends Record<string, string>>(def: Def, y: string) {
    let x = def[y] || def.a
}
work(def_val, 'foo') // ok

您也可以使用 custom typeguard:


const def_val = { a: "debug", b: "info", c: "warning" };

const isValidKey = (key: string): key is keyof typeof def_val =>
    /a|b|c/.test(key)

const work = (y: string) => isValidKey(y) ? def_val[y] : def_val.a

work('foo') // ok

P.S。 Here 您可以找到有关使用内置实用程序类型的文档,例如 RecordPartial 等...