Typescript泛型,使用泛型字段作为映射类型

Typescript泛型,使用泛型字段作为映射类型,typescript,generics,Typescript,Generics,可怕的标题,我知道!我不知道如何简明扼要地描述这一点 我试图创建一个函数,它接受一个对象数组,每个对象都有一个“type”字段,以及一组处理各种类型的函数 下面的代码是我正在做的尝试: 您可以在对handler的调用中看到我试图描述的对象 type Foo = {type: "foo", name: string} type Bar = {type: "bar", score: number} type Props<T extends {type:

可怕的标题,我知道!我不知道如何简明扼要地描述这一点

我试图创建一个函数,它接受一个对象数组,每个对象都有一个“type”字段,以及一组处理各种类型的函数

下面的代码是我正在做的尝试:

您可以在对handler的调用中看到我试图描述的对象

type Foo = {type: "foo", name: string}
type Bar = {type: "bar", score: number}

type Props<T extends {type: string}> = {
  variables: T[];
  functions: {
    [k in T["type"]]: (args: T) => void;
  }
}

function handler<T extends {type: string}>({variables, functions}: Props<T>) {
  variables.forEach(v => {
    functions[v.type](v); 
    // ^^^^^^^^^^^^^
    // No index signature with a parameter of type 'string' was found on type '{ [k in T["type"]]: (args: T) => void; }'.
  })
}

handler({
  variables: [{type: "foo", name: ""}, {type: "bar", score: 0}],
  functions: {
    "foo": (args) => {args.name}, // <--- args has type Foo | Bar, ideally would just be Foo
    "bar": (args) => {args.score},
  }
})
type Foo={type:“Foo”,name:string}
类型栏={类型:“栏”,分数:数字}
类型道具={
变量:T[];
职能:{
[k in T[“type”]:(args:T)=>void;
}
}
函数处理程序({variables,functions}:Props){
variables.forEach(v=>{
函数[v.type](v);
// ^^^^^^^^^^^^^
//在类型“{[k in T[“type”]]:(args:T)=>void;}”上未找到具有“string”类型参数的索引签名。
})
}
处理者({
变量:[{type:“foo”,name::},{type:“bar”,分数:0}],
职能:{
“foo”:(args)=>{args.name},//{args.score},
}
})

我不确定哪里出了问题,如果有任何帮助,我们将不胜感激。

您可以在道具类型定义中将键设置为字符串

type Props<T extends {type: string}> = {
  variables: T[];
  functions: {
    [k in T["type"] as string]: (args: T) => void;
  }
}
类型道具={
变量:T[];
职能:{
[k在T[“type”]中作为字符串]:(args:T)=>void;
}
}
但是,您已经注意到在代码中没有使用Foo和Bar类型。 按如下方式使用它们会抛出一个错误,表明您的设计中存在错误

type Foo = {type: "foo", name: string}
type Bar = {type: "bar", score: number}

type Props<T extends {type: string}> = {
  variables: T[];
  functions: {
    [k in T["type"] as string]: (args: T) => void;
  }
}

function handler<T extends {type: string}>({variables, functions}: Props<T>) {
  variables.forEach(v => {
    functions[v.type](v); 
    
  })
}

handler<Foo | Bar>({
  variables: [{type: "foo", name: ""}, {type: "bar", score: 0}],
  functions: {
    "foo": (args:Foo) => {args.name}, // <--- error here as name is not in Bar
    "bar": (args:Bar) => {args.score}, // <--- error here as name is not in Foo
  }
})
type Foo={type:“Foo”,name:string}
类型栏={类型:“栏”,分数:数字}
类型道具={
变量:T[];
职能:{
[k在T[“type”]中作为字符串]:(args:T)=>void;
}
}
函数处理程序({variables,functions}:Props){
variables.forEach(v=>{
函数[v.type](v);
})
}
处理者({
变量:[{type:“foo”,name::},{type:“bar”,分数:0}],
职能:{
“foo”:(args:foo)=>{args.name},//{args.score}//