簡體   English   中英

我可以在TypeScript中指定值類型,但仍然讓TS推斷鍵類型嗎?

[英]Can I specify a value type in TypeScript but still let TS deduce the key type?

如果我在TypeScript中創建此常量:

const PARAMS = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

它推導類型為{ green: {color: number}; black: { color: number }; white: { color: number }; } { green: {color: number}; black: { color: number }; white: { color: number }; } { green: {color: number}; black: { color: number }; white: { color: number }; }

但是我從上下文知道值的類型應該是THREE.MeshBasicMaterialParameters 我可以使用索引類型來聲明:

const PARAMS: {[name: string]: THREE.MeshBasicMaterialParameters} = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

但隨后我失去了按鍵的特定可能性(“綠色”,“黑色”或“白色”)。 我可以通過寫出所需的完整類型來更精確地建模:

const PARAMS: {
  green: THREE.MeshBasicMaterialParameters,
  black: THREE.MeshBasicMaterialParameters,
  white: THREE.MeshBasicMaterialParameters
} = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

但這是非常冗長和重復的。

有沒有一種方法可以更簡潔地獲取我想要的類型?

您可以通過使用通用映射類型來減少詳細程度

type ParamsType<Colors extends string> = {
    [c in Colors]: THREE.MeshBasicMaterialParameters;
}

const PARAMS: ParamsType<'green' | 'black' | 'white'> = {
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
};

但是您仍然必須重復兩次顏色名稱。 如果希望打字稿推斷出鍵,則必須引入中間函數,在運行時完全沒有用。 我不知道有什么其他方法可以使Typescript來推斷通用參數-github上有一項提議允許扣除默認模板參數,但到目前為止沒有實現。

function inferColorKeys<Colors extends string>(params: ParamsType<Colors>): ParamsType<Colors> {
    return params;
}


const PARAMS = inferColorKeys({
  green: {color: 0x007700},
  black: {color: 0x000000},
  white: {color: 0xffffff},
});

UPDATE

您可以按照@jcalz的建議,使其完全通用,方法是將inferKeys變成一個帶有顯式通用參數並返回一個推斷其通用參數的函數。 它必須是兩個函數,因為一個函數不能具有某些顯式的通用參數和某些推斷的參數。 而且,它使用了內置的Record類型,該類型定義為type Record<K extends string, V> = {[k in K]: V}

const inferKeys = <V>() => <K extends string>(x: Record<K,V>): Record<K,V> => x;

const PARAMS = inferKeys<THREE.MeshBasicMaterialParameters>()({
    green: {color: 0x007700},
    black: {color: 0x000000},
    white: {color: 0xffffff},
});

PARAMS類型推斷為

Record<"green" | "black" | "white", THREE.MeshBasicMaterialParameters>

這是您的選擇嗎?

const PARAMS = {
  green: {color: 0x007700} as THREE.MeshBasicMaterialParameters,
  black: {color: 0x000000} as THREE.MeshBasicMaterialParameters,
  white: {color: 0xffffff} as THREE.MeshBasicMaterialParameters,
};

暫無
暫無

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

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