Typescript区分联合参数类型-一个参数类型依赖于另一个参数类型

j8ag8udp  于 2023-03-24  发布在  TypeScript
关注(0)|答案(1)|浏览(155)

我尝试键入一个可以接受templateparams参数的函数,其中params是一个联合类型,应该通过从template的类型中缩小类型来推断。
下面是代码:

enum Template {
  TEMPLATE_1,
  TEMPLATE_2,
}

type CreateTemplate1Params = {
  x: string,
  y: string,
  z: string,
}

type CreateTemplate2Params = {
  y: string,
}

type TemplateCreateParamsMap = {
  [Template.TEMPLATE_1]: CreateTemplate1Params,
  [Template.TEMPLATE_2]: CreateTemplate2Params,
}

const createTemplate1 = (params: CreateTemplate1Params) => {
  return
}

const createTemplate2 = (params: CreateTemplate2Params) => {
  return
}

const sendTemplate = <T extends keyof TemplateCreateParamsMap>(
  { template, params }: { template: T, params: TemplateCreateParamsMap[T] }
) => {
  switch (template) {
    case Template.TEMPLATE_1:
      // This isn't working - type of 'params' isn't being inferred properly
      // Type 'CreateTemplate2Params' is missing the following properties from type 'CreateTemplate1Params': x, z
      createTemplate1(params);
      break;
    case Template.TEMPLATE_2:
      createTemplate2(params);
      break;
    default:
      return
  }
}

我做错了什么,为什么在sendTemplate函数中参数的类型没有缩小到正确的CreateTemplateXParams

lx0bsm1f

lx0bsm1f1#

问题是{ template: T, params: TemplateCreateParamsMap[T] }并没有创建一个可区分的并集。相反,它给了我们这样的类型:

{
    template: keyof TemplateCreateParamsMap;
    params: CreateTemplate1Params | CreateTemplate2Params;
}

要创建区分联合,您可以使用分布式条件类型:

const sendTemplate = <T extends keyof TemplateCreateParamsMap>(
  { template, params }: T extends T ? { template: T, params: TemplateCreateParamsMap[T] } : never
) => {

Playground

相关问题