TypeScript:如何用字符串数组泛型实现动态键值的通用对象
解决方案
当然可以,两种需求都能实现,具体看你想要哪种数据结构:
情况1:data仍为对象,支持多函数键
修改原接口的泛型约束,让它接受字符串数组,通过T[number]提取数组中的所有字符串元素作为对象的键:
interface TestInterface<T extends readonly string[]> { data: { [K in T[number]]: () => void; } } // 使用示例 const testCommand: TestInterface<["fun1", "fun2", "fun3"]> = { data: { fun1: () => { // do something }, fun2: () => { // do something }, fun3: () => { // do something }, } }; // 类型会自动提示,只能访问fun1/fun2/fun3 testCommand.data.fun1();
情况2:data改为数组结构
如果想让data是包含name和exec的数组,甚至严格对应泛型数组的顺序,可以这样定义接口:
严格对应泛型顺序(元组类型)
这种写法会让数组元素的name和泛型数组的位置严格匹配:
interface TestInterface<T extends readonly string[]> { data: { [I in keyof T]: { name: T[I]; exec: () => void } }; } // 使用示例 const testCommand: TestInterface<["fun1", "fun2", "fun3"]> = { data: [ { name: "fun1", exec: () => {} }, { name: "fun2", exec: () => {} }, { name: "fun3", exec: () => {} }, ] }; // 按索引访问时,类型会自动提示对应name testCommand.data[0].exec();
不要求顺序的数组
如果只需要数组元素的name属于泛型中的字符串,不需要严格顺序,可以简化:
interface TestInterface<T extends readonly string[]> { data: Array<{ name: T[number]; exec: () => void }>; }
内容的提问来源于stack exchange,提问作者Bennet
相关产品推荐
相关产品推荐

