在 TypeScript 中,当需要定义一个函数参数为对象类型但不确定对象的具体属性名时,可以通过以下几种方式实现:
适用于对象属性名动态但值类型固定的场景:
function processObject(obj: { [key: string]: unknown }) {
// `key`可以是任意字符串,值类型为`unknown`(或其他具体类型)
console.log(Object.keys(obj));
}
processObject({ a: 1, b: "hello" }); // 允许任意属性名
优势:
string
、number
等)。限制:
Record<Keys, Type>
工具类型适用于明确键和值类型的场景:
function processRecord(obj: Record<string, number>) {
// 键为字符串,值为数字
console.log(Object.values(obj).reduce((a, b) => a + b, 0));
}
processRecord({ age: 30, score: 100 }); // 合法
优势:
如果部分属性名已知,部分未知:
function processMixed(obj: { id: string } & { [key: string]: boolean }) {
// 必须包含`id: string`,其他属性为`boolean`
console.log(obj.id, Object.keys(obj));
}
processMixed({ id: "123", active: true }); // 合法
当需要保留传入对象的字面量类型时:
function processGeneric<T extends object>(obj: T) {
// `T`会被推断为传入对象的实际类型
console.log(obj);
}
processGeneric({ unknownKey: 42 }); // 类型推断为 `{ unknownKey: number }`
优势:
unknown
或 any
(不推荐)仅在完全无法预测结构时使用:
function processAny(obj: unknown) {
if (typeof obj === "object" && obj !== null) {
console.log("对象结构未知,需运行时检查");
}
}
注意:牺牲类型安全性,应优先选择前几种方案。
若遇到类型错误:
Record<string, T>
或索引签名。any
,通过运行时检查保障逻辑安全。