推断对象内部的函数参数

问题描述 投票:0回答:1

我正在创建一个对象,如下所示:

type AllLiterals = "one" | "two" | "three";

type ObjectConfig<T=unknown> = {
  path: string;
  value: AllLiterals;
  createPath?: (params:T)=>string
}

const config: Record<AllLiterals,ObjectConfig> = {
  one: {
    path: "one-path",
    value: "one",

  },
  two: {
    path: "two-path",
    value: "two",
    createPath: (params:{a:string})=>`two-path/${params}`
  },
  three: {
    path: "three-path",
    value: "three",
    createPath: (params:{a:string,b:string})=>`three-path/${a}/${b}`
  }
}

当我尝试使用createPath时,typescript无法正确推断参数类型,我该如何解决这个问题?

typescript
1个回答
0
投票

您必须定义泛型类型,params 中的键将是 genericType 中的键,您不需要所有键,因为在函数中您直接传递特定类型,如 params: { a: string } 所以TypeScript 不需要 createPath 中的参数来匹配 genericType 类型的所有属性。

type AllLiterals = "one" | "two" | "three";

type ObjectConfig<T=unknown> = {
     path: string;
  value: AllLiterals;
  createPath?: (params:T)=>string
}

interface GenericType {
  a: string; 
  b: string; 
  c: string; 
}
 
 

const config: Record<AllLiterals,ObjectConfig<GenericType>> = {
  one: {
    path: "one-path",
    value: "one",
  },
  two: {
    path: "two-path",
    value: "two",
    createPath: (params:{a:string })=>`two-path/${params.a}`
  },
  three: {
    path: "three-path",
    value: "three",
    createPath: (params:{ a: string; b: string })=>`three-path/${params.a}/${params.b}`
  }
}

如果您想要包含多个类型的 genericType 的联合类型,您需要将 createPath 的类型声明更改为 genericType 本身,以便它需要 genericType 的所有属性。

问题是联合类型不知道要匹配哪一个,所以在做某事之前你必须使用 in 检查对象中的属性

type AllLiterals = "one" | "two" | "three";

type ObjectConfig<T = unknown> = {
  path: string;
  value: AllLiterals;
  createPath?: (params: T) => string;
};

type GenericType = { a: string; b: string } | { a: string };

const config: Record<AllLiterals, ObjectConfig<GenericType>> = {
  one: {
    path: "one-path",
    value: "one",
  },
  two: {
    path: "two-path",
    value: "two",
    createPath: (params: GenericType) => `two-path/${params.a}`, 
  },
  three: {
    path: "three-path",
    value: "three",
    createPath: (params: GenericType) => {
      if ('b' in params) {
        return `three-path/${params.a}/${params.b}`;
      }
      return `three-path/${params.a}`;
    },
  },
};
© www.soinside.com 2019 - 2024. All rights reserved.