代码之家  ›  专栏  ›  技术社区  ›  Konrad Viltersten

除非声明为常量,否则无法通过将变量用作索引名称来访问TypeScript中对象的字段

  •  -3
  • Konrad Viltersten  · 技术社区  · 2 月前

    我不明白为什么前两个打印输出有效,而另外两个输出会产生错误。

    const index1 = "name";
    const holder: { field: string; } = { field: "name" };
    const index2 = holder.field;
    
    const target = { name: "beep" } as MyType;
    
    console.log(target["name"]);
    console.log(target[index1]);
    
    console.log(target[holder.field]);
    console.log(target[index2]);
    

    错误显示:

    TS7053:元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引“MyType”类型。
    在类型“MyType”上找不到具有“string”类型参数的索引签名。

    如何通过来自非常量的变量名获取字段?

    我还没有找到以我认可的方式解决这个具体问题的好答案。最令人困惑的是,我 在这两种情况下,都使用字符串来获取对象中的字段。唯一的区别是 const 宣言。

    我已尝试添加 as const 根据没有任何区别的示例。

    字段值来自此接口。它肯定是一个字符串。在上面的示例中,我甚至简化了类型定义。

    export interface SortInfo {
      field: string;
      direction: number;
    }
    

    我试图从中获取字段的对象本身由此接口声明。

    export interface MyType {
      id: string;
      name: string;
      type: number;
      ...
    }
    
    1 回复  |  直到 2 月前
        1
  •  1
  •   njzk2    2 月前

    TypeScript告诉我们,它无法确定您使用的密钥对此对象有效。

    就像 target["foobar"] 无法编译,也无法编译 target[key] 如果类型 key string .

    你需要钥匙的类型 keyof typeof target ,或者就你而言 keyof MyType ,即 "id" | "name" | "type" | ...

    您可以定义 holder 作为 { field: keyof MyType; } :

    const holder: { field: keyof MyType; } = { field: "name" };
    console.log(target[holder.field]); // This works fine
    

    如果那种类型真的应该 SortInfo ,然后您可以使用

    export interface SortInfo {
      field: keyof MyType;
      direction: number;
    }
    

    当然,如果 MyType 可以是你使用泛型的不同东西:

    export interface SortInfo<T> {
      field: keyof T;
      direction: number;
    }