在 TypeScript 里,若要定義一個鍵為string
類型、值為number
類型的對象,并且不使用interface
和type
,可以采用以下幾種方式:
1. 內聯類型注解(Inline Type Annotation)
直接在變量聲明時使用索引簽名進行類型約束:
typescript
const obj: { [key: string]: number } = {a: 1,b: 2,"key-with-dash": 3 // 合法:鍵為string,值為number
};// 錯誤示例:
// obj.c = "hello"; // 類型錯誤:不能將string賦值給number
// obj[123] = 4; // 類型錯誤:索引類型必須為string
2. 泛型約束(Generic Constraint)
使用泛型函數或類,并通過約束強制要求對象符合結構:
typescript
function processNumbers<T extends { [key: string]: number }>(obj: T) {return Object.values(obj).reduce((sum, num) => sum + num, 0);
}const result = processNumbers({ x: 10, y: 20 }); // 正確
// processNumbers({ a: "invalid" }); // 錯誤:值必須為number
3. 映射類型(Mapped Type)
利用內置映射類型(如Record
)來約束對象結構:
typescript
const obj: Record<string, number> = {apple: 1,banana: 2
};// 等同于:{ [P in string]: number }
4. 類型斷言(Type Assertion)
在創建對象時直接斷言其類型:
typescript
const obj = { a: 1, b: 2 } as { [key: string]: number };// 后續賦值會被類型檢查:
obj.c = 3; // 正確
// obj.d = "text"; // 錯誤
5. 函數返回值類型
在函數返回值位置直接定義類型:
typescript
function createNumberMap(): { [key: string]: number } {return {one: 1,two: 2};
}const map = createNumberMap();
map.three = 3; // 正確
總結
不使用interface
和type
時,可通過以下方式定義鍵值類型約束:
- 索引簽名:
{ [key: string]: number }
- 內置映射類型:
Record<string, number>
- 泛型約束:
T extends { [key: string]: number }
- 類型斷言:
obj as { [key: string]: number }
這些方法本質上都是通過 ** 類型字面量(Type Literal)** 直接在使用處定義類型,避免了顯式聲明interface
或type
別名。
編輯
分享
如何使用泛型約束來定義一個鍵為string類型、值為number類型的對象?
除了上述兩種方式,還有其他方法可以定義鍵為string類型、值為number類型的對象嗎?
在TypeScript中,定義一個鍵為string類型、值為任意類型的對象的方法是什么?