[英]Change function return type based on input tranformer function in Typescript
What I am trying to do is create a simple function that would optionally accept a transformer
method as input and return:我想要做的是创建一个简单的函数,它可以选择接受一个
transformer
方法作为输入并返回:
transformer
provided)transformer
)transformer
's return type.transformer
返回类型的转换结果。 A small example to showcase what I mean is the following:展示我的意思的一个小例子如下:
// our basic example interface
interface Person {
name: string;
age: number
};
// the transformer fn type
type TransformerFn = <T>(person: Person) => T;
// method options contaning the optional transformer method param
interface mapperOpts {
paramA?: number
transformer?: TransformerFn
}
// Conditional type for returning the result based on providing transformer in options or not
type OriginalOrTransformedPerson<T extends Partial<mapperOpts>> = T extends { transformer: TransformerFn } ?
ReturnType<T['transformer']> :
Person;
// test class interface
interface PeopleGetter {
getPeople<T extends Partial<mapperOpts>>(people: Person[], opts: T): OriginalOrTransformedPerson<T>
}
class Test implements PeopleGetter {
getPeople(people: Person[], opts: Partial<mapperOpts>) {
if (opts.transformer) {
return people.map(opts.transformer);
} else {
return people;
}
}
}
const people: Person[] = [{ name: 'john', age: 20 }];
const test = new Test();
const original = test.getPeople(people); // here we should have `Person[]`
const transformedResult = test.getPeople(people, { transformer: (person: Person) => person.name }); // here I would like to have the return type of 'string[]' based on transformer method
Typescript playground here打字稿操场在这里
I tried to follow the plain map
implementation of Array<T>
interface which properly infers the return type of the provided callback method in map
but I could not get it to work.我试图遵循
Array<T>
接口的普通map
实现,它正确推断了map
提供的回调方法的返回类型,但我无法让它工作。 I get errors in getPeople
implementation and usage.我在
getPeople
实现和使用中遇到错误。
Any ideas?有任何想法吗?
I tried to simplify and create a more generic version of the problem and posted it here: Typescript method return type based on optional param property function我试图简化并创建一个更通用的问题版本并将其发布在这里: Typescript method return type based on optional param property function
With the really generous help and explanation of @jcalz I was able to also create a version that works for my original post here.在@jcalz 非常慷慨的帮助和解释下,我还能够创建一个适用于我的原始帖子的版本。 The thing it that Type Inference is a really complicated matter for Typescript and not everything is automatically inferred as someone would expect to.
类型推断对于 Typescript 来说是一件非常复杂的事情,并不是所有的事情都会像人们期望的那样自动推断出来。 Important conclusions are:
重要的结论是:
Having said that, here is the version that works for my original question:话虽如此,这是适用于我的原始问题的版本:
// our basic example interface
interface Person {
name: string;
age: number
};
// the transformer fn type
type TransformerFn<T = any> = (person: Person) => T;
// method options contaning the optional transformer method param
interface mapperOpts<T = any> {
paramA?: number
transformer?: TransformerFn<T>
}
// Conditional type for returning the result based on providing transformer in options or not
type OriginalOrTransformedPerson<T> = T extends { transformer: TransformerFn<infer R> } ?
R :
Person;
// test class interface
interface PeopleGetter {
getPeople<T extends Partial<mapperOpts>>(people: Person[], opts: T): OriginalOrTransformedPerson<T>[]
}
class Test implements PeopleGetter {
getPeople<T extends Partial<mapperOpts>>(people: Person[], opts?: T): OriginalOrTransformedPerson<T>[] {
if (opts?.transformer) {
return people.map(opts.transformer);
} else {
return people as OriginalOrTransformedPerson<T>[];
}
}
}
const people: Person[] = [{ name: 'john', age: 20 }];
const test = new Test();
const original = test.getPeople(people); // here we should have `Person[]`
const transformedResult = test.getPeople(people, { transformer: (person: Person) => person.name }); // here I would like to have the return type of 'string[]' based on transformer method
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.