簡體   English   中英

如何在 TypeScript 中使用動態鍵定義 object 類型?

[英]How to define an object type with dynamic keys in TypeScript?

我有一個 const object 看起來像這樣:

export const Language: Values = {
  es: {urlValue: 'es', label: 'Spain'},
  en: {urlValue: 'en', label: 'Anything'},
  eb: {urlValue: 'eb', label: 'Other thing'},
};

export interface Values {
  [name: string]: Value;
}

export interface Value {
  urlValue;
  label;
  selected?;
}

現在在應用程序的某個地方,我們讀取了一些具有這種格式的數據,它們恰好具有完全相同的鍵:

{
  es: 32,
  en: 11,
  eb: 56
}

所以實際上我需要另一個 object 類型,如下所示:

export class AnotherObject {

  constructor(public es: number,
              public en: number,
              public eb: number) {
  }
}

但是我可以動態創建這種類型,以便它自動使用語言 object 的鍵或“值”類型的 urlValue 嗎?

PS:問題是我們確切用例的簡化形式,其中我們有多個常量,如語言。 因此,自動化將非常有幫助。

編輯:對於@basarat 的建議-由於此 object 是父 object 的一部分,因此我實際上需要在此部分中定義類型:

export class ParentObject {
  thatObjectAbove: AnotherObject;
  otherObjects: ..
  ..
}

export interface AnotherObject {
  [name: LanguageOptions]: number;
}

我有錯誤“索引簽名參數類型不能是聯合類型。請考慮改用映射的 object 類型。” 在“[名稱:LanguageOptions]:數字;”行的“名稱”部分

keyof類型運算符為您提供作為類型的鍵名:

export const Language = {
  es: {urlValue: 'es', label: 'Spain'},
  en: {urlValue: 'en', label: 'Anything'},
  eb: {urlValue: 'eb', label: 'Other thing'},
};

type LanguageOptions = keyof typeof Language; // 'es' | 'en' | 'eb'

你可能會改變你的代碼嗎?

class DynamicClass<T> {
    constructor(values?: { [key in keyof T]?: T[key] }) {
        for (const key of Object.keys(values)) {
            this[key] = values[key];
        }
    }
}

class MyClass extends DynamicClass<MyClass> {
    attr1: string;
    attB: number;
    obj: {
        wow: string,
        yeah: boolean
    };
}


new MyClass({
    attr1: 'a',
    obj: {
        wow: '',
        yeah: true
    },
    att
})

在此處輸入圖像描述

繼續這個答案

我已經實現了將 AnotherObject 定義為類型而不是接口的目標。

type LanguageOptions = keyof typeof Language;  // as from basarat's answer

type AnotherObject = {[key in LanguageOptions]: number}; // is actually a type, still is named as 'object' so that it is still compatible with the question's code
    
export class ParentObject {
  thatObjectAbove: AnotherObject;
  otherObjects: ..
  ..
}

正如這里所說,這是因為 typescript 的奇怪行為,可以通過這種方式修復。

因此,單線的最終解決方案:

thatObjectAbove: {[key in keyof typeof Language]: number};

或者

thatObjectAbove: Record<keyof typeof Language, number>;  // Record is a built-in typescript type

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM