TypeScript泛型和函数参数条件类型

时间:2020-07-21 11:20:45

标签: typescript typescript-generics

假设我有一个函数,该函数返回传入的getIdentifier函数的返回值。该功能是强制性的,除了item具有id属性的情况之外,因为我可以回过头来阅读它。

type FuncArg<T> = T extends { id: string }
  ? { item: T; getIdentifier?: (item: T) => string }
  : { item: T; getIdentifier: (item: T) => string };

type withId<T> = T & { id: string };

const getFoobar = <T>(arg: FuncArg<T>) => {
  return arg.getIdentifier ? arg.getIdentifier(arg.item) : (arg.item as withId<T>).id;
};

到目前为止一切顺利。假设我有第二个函数,它将一个项目传递给第一个函数,检查它是否具有id,如果没有,则将其传递给随机生成器getIdentifier

const getFoobar2 = <T>(item: T) => {
  if ('id' in item) return getFoobar({item: item as withId<T>});
  return getFoobar({item: item, getIdentifier: () => Math.random().toString()});
}

不幸的是,最后一个示例中的类型检查失败,我不知道要解决此问题。我已经尝试了从条件类型到联合类型和函数重载的所有内容。每次我遇到类似的问题。我在这里想念什么?

Playground ▶

1 个答案:

答案 0 :(得分:1)

您错过了item函数签名中的getIdentifier参数,并且看起来它在对象声明中需要显式as FuncArg<T>。无法解释得更好,在打字稿方面经验不足。

const getFoobar2 = <T>(item: T) => {
  if ('id' in item)
    return getFoobar({ item: item } as FuncArg<T>);
  return getFoobar({item: item, getIdentifier: (item: T) => Math.random().toString()} as FuncArg<T>);
}