TypeScript通用联合类型

3

我有一组泛型对象的数组,想要遍历它们,但 TypeScript 不允许这样做。以下是一些示例代码。有什么建议可以解决这个问题。

type someGeneric<T> = { item: T };

type stringGeneric = someGeneric<string>;

type numberGeneric = someGeneric<number>;

type someFunction = <T>(generic: someGeneric<T>) => T;

const someFunction: someFunction = (generic) => generic.item;

const stringGeneric: stringGeneric = { item: 'some String' },
    numberGeneric: numberGeneric = { item: 12 };

let genericArray = [stringGeneric, numberGeneric];
genericArray.forEach(generic => {
    someFunction(generic); // Error On This line.
});

您可以将代码复制并粘贴到此链接中。我好像无法分享这段代码。

2
这一行出现错误” 请问是什么错误? - MTCoster
@MTCoster 错误(重要部分)是Argument of type 'someGeneric<string> | someGeneric<number>' is not assignable to parameter of type 'someGeneric<string>'。 - Titian Cernicova-Dragomir
1
虽然有些跑题,但我可以建议您在类型名称上始终使用TitleCase格式,例如SomeGeneric<T>。这与TS社区和TS团队的代码相匹配。 - CodeAndCats
1个回答

4
问题在于函数接受类型为someGeneric<T>的参数。如果我们试图传递类型为someGeneric<number> | someGeneric<string>的参数,TypeScript不会尝试从中推断出 T 的值,而只会显示联合类型与someGeneric<T>这种类型不兼容。
我们可以更改函数定义,使得类型参数继承someGeneric<any>,这个限制将与联合类型兼容。然后,我们可以使用条件类型从T中提取出项目类型。由于条件类型在联合类型上分发,因此提取的结果将是someGeneric<T>的通用参数的联合。
type someGeneric<T> = { item: T };

type stringGeneric = someGeneric<string>;

type numberGeneric = someGeneric<number>;

type extractItemFromSomeGeneric<T extends someGeneric<any>> = T extends someGeneric<infer U> ? U : never;  
type someFunction = <T extends someGeneric<any>>(generic: T) => extractItemFromSomeGeneric<T>;

const someFunction: someFunction = (generic) => generic.item;

const stringGeneric: stringGeneric = { item: 'some String' },
    numberGeneric: numberGeneric = { item: 12 };

let someGeneric = [stringGeneric, numberGeneric];
someGeneric.forEach(generic => {
    someFunction(generic); // retruns string | number
});

Playground链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接