typescript - 根据 Typescript 中的输入转换器函数更改函数返回类型
问题描述
我想做的是创建一个简单的函数,它可以选择接受一个transformer
方法作为输入并返回:
- 原始结果(如果未
transformer
提供) - 或基于
transformer
的返回类型的转换结果。
展示我的意思的一个小例子如下:
// 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
打字稿游乐场在这里
我试图遵循接口的简单map
实现,Array<T>
它正确地推断出提供的回调方法的返回类型,map
但我无法让它工作。getPeople
我在实施和使用中遇到错误。
有任何想法吗?
解决方案
我试图简化并创建一个更通用的问题版本并将其发布在这里:Typescript method return type based on optional param property function
在@jcalz 非常慷慨的帮助和解释下,我还能够创建一个适用于我的原始帖子的版本。类型推断对于 Typescript来说是一件非常复杂的事情,并不是所有的事情都会像人们期望的那样自动推断出来。重要的结论是:
- 类型推断不考虑通用约束
- 类型推断不能部分工作。您可以在类型化函数使用中提供所有类型参数,或者不提供。您不能提供其中一个类型参数并让其他类型参数被推断出来。
话虽如此,这是适用于我原来问题的版本:
// 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
推荐阅读
- reactjs - 在react js中更新数据库后firebase检索数据问题
- excel - TextJoin 删除重复项但使用 If 函数过滤器
- kotlin - 如何让 kotlin-logging (MicroUtils) 打印到子类名而不是抽象类名?
- amazon-ec2 - 在 Ubuntu 18.04 上启动 google-chrome-stable 时出现分段错误
- rundeck - rundeck 问题 - 启用活动自动刷新 - 默认情况下禁用
- amazon-web-services - AWS:STS Assume Role 不适用于用户
- javascript - 使用 Knex.js 批量插入错误:绑定消息提供 X 参数,但准备好的语句“”需要 Y
- mysql - 如何优化以下 SELECT 查询
- python - 在函数列表中选择和执行函数
- common-lisp - 为什么斐波那契数列的结果在一定数量后开始发散?