说我有这种类型:
export type Transformer = <T extends any[], U>(
data: T,
) => U;
我有这个功能,我想要符合这种类型:
export const transform: Transformer = (
data: Result[]
): { data:Result[] } => {
if (!data) {
return { data: [] };
}
data.forEach((record:Result) => {
record.extraStuff = {
foo: 'bar'
};
});
return { data: data };
};
编译器抱怨:
Type '(data: Result[]) => { data: RecordMatchingSearchResult[]; }' is not assignable to type 'Transformer'.
Type '{ data: Result[]; }' is not assignable to type 'U'.
我是否需要向U添加通用约束以推断它。
我也没有编写类型,但它似乎有点奇怪,它不接受泛型参数,但它们存在于函数中。
答案 0 :(得分:3)
你的功能问题在于它并不是真正的通用。您有一个通用函数签名(Transformer
),并且您尝试分配一个非通用的函数。
返回类型特别是因为返回类型必须由调用者指定,因此调用者将指望它指定的返回类型而不是非泛型结果({ data: Result[] }
)。如果允许您的分配,则此调用将导致运行时错误:
let result = transform<Result[], { other: number }>([]);
result.other // this would cause an error
如果结果的类型是固定的,你应该声明它,并且函数实现本身应该是通用的:
export type Transformer = <T extends { extraStuff: any }>(
data: T[],
) => { data: T[] };
class Result {
extraStuff: any;
}
export const transform: Transformer = <T extends { extraStuff: any }>(data: T[]): { data: T[] } => {
if (!data) {
return { data: [] };
}
data.forEach((record: T) => {
record.extraStuff = {
foo: 'bar'
};
});
return { data: data };
};
或者您可以将Transfomer
的泛型从函数签名移动到类型,并在声明transform
函数时指定类型参数,因此函数本身不必是通用的:
export type Transformer<T extends { extraStuff: any }, U> = (
data: T[],
) => U;
export const transform: Transformer<Result, { data: Result[] }> = (data: Result[]): { data: Result[] } => {
if (!data) {
return { data: [] };
}
data.forEach((record: T) => {
record.extraStuff = {
foo: 'bar'
};
});
return { data: data };
};