typescript 类型脚本:泛型,如果给定键,则推断对象的值

pkln4tw6  于 2023-02-10  发布在  TypeScript
关注(0)|答案(1)|浏览(142)

假设我们有一个调度函数试图更新一个对象上的某个属性,那么在下面的场景中是否有可能进行正确的类型推断?

type EntityA = {
  name: string;
  id: number
}

type EntityB = {
  id: number;
  test1: number;
  test2: string;
  test3: number;
  test4: string;
}

type EntityAction<T> = {
  [K in keyof T]-?:
  | {
    type: 'UPDATE_ENTITY';
    payload: T;
  } |
  {
    type: 'UPDATE_PROP';
    propName: K;
    payload: T[K];
  };
}[keyof T];

function dispatch<T>(action: EntityAction<T>) {
  // omitted logic because it's not relevant
  console.log(action);
}

dispatch<EntityA>({
  type: 'UPDATE_PROP',
  propName: 'name',
});

dispatch<EntityB>({
  type: 'UPDATE_PROP',
  propName: 'test4',
  payload: ''
})

这里是Playground
我设法根据here(Thanks@jcalz)找到的回复来推断类型,但只要我在一个类型中有超过1个属性,它就不能正常工作。
给定EntityA,如果我分派以下内容:

dispatch<EntityA>({ type: 'UPDATE_PROP',propName: 'id' })

它正确地让我知道属性payload缺失但是,如果我通过

dispatch<EntityA>({ type: 'UPDATE_PROP',propName: 'name' })

它告诉我Type '"name"' is not assignable to type '"id"'.(或者类型中最后一个属性是什么)。
是否可以"修复"此问题以正确推断payload的类型?在此设置中是否可能?如果EntityAction为以下形式,则似乎可以工作:

export type EntityAction<T> = {
  [K in keyof T]-?:
  {
    type: 'UPDATE_PROP';
    propName: K;
    payload: T[K];
  };
}[keyof T];
nnt7mjpx

nnt7mjpx1#

这看起来像是microsoft/TypeScript#46374报告的一个已知错误,在该错误中,分配给区分联合的“不完整”值产生编译器错误,该错误抱怨错误的属性。
它看起来像是在TypeScript 3.9中引入的,在typescript@3.9.0-dev.20200328typescript@3.9.0-dev.20200407之间的某个时候,这让我相信它可能是由microsoft/TypeScript#37589中所做的工作引起的,“生成错误消息时不允许判别属性的部分匹配”,它改变了生成判别联合错误消息的方式,修复了一个不同的bug,但显然导致了这个bug。
无论如何,这个bug目前计划在TypeScript 5.1中修复,但是它已经被重新安排了几次,所以不清楚这是否真的会发生。

相关问题