有没有办法让 TypeScript 根据调用参数推断函数返回值的类型?

马科斯

我正在设置一个从我的数据库中检索数据的函数。它接受一个键字符串作为参数,并根据键返回不同的数据类型。

我的目标是让 TypeScript 根据作为参数传递的键来推断将返回的类型。

这是我尝试过的:

interface Fruits { names: string[] }
interface Employees { ages: number[] }

function getData(key: "fruits" | "employees") {
  if (key === "fruits") {
    // fetch data for /fruits and return it, specifying its type
    return { names: ["apple", "orange", "kiwi"] } as Fruits;
  }

  // fetch data for /employees and return it, specifying its type
  return { ages: [30, 50, 19 ] } as Employees;
}

const fruits = getData("fruits"); 
// ...should infer that the returned value will be of type 'Fruits'
        
const fruitNames = fruits.names; 
// ...fails to infer type. Thinks fruits is of type (Fruits | Employees)

最后一行给出了一个警告,因为 TypeScript 无法推断在调用 getData 时使用键“fruits”将始终返回 Fruits 类型的值(反过来,它具有属性“names”)。

当然,我也可以通过像这样对 getData 的调用进行类型转换来消除错误:

const fruits = getData("fruits") as Fruits;

但是,在我看来,这首先违背了使用 TypeScript 的目的,因为我的代码再次变得非常容易出错。例如,如果我进行了错误的类型转换,技术上不正确的代码将不会发出任何警告:

const fruits = getData("fruits") as Employees;
const nonexistent = fruits.ages; 
// TS won't complain about any accesses to the non-existent property 'ages' 
// because I made the wrong typecasting

我的目标是,任何使用 getData 函数的人都可以提前知道,多亏了 TypeScript 的 IntelliSense,只要他们提供了用于查询数据的“键”字符串,他们就会返回的数据类型。调用函数时不需要手动转换函数的返回值类型。

在 getData 内部,任何类型转换、泛型的使用或任何其他类型都可以。但是,除此之外,给函数一个有效的键参数应该足以让 TypeScript 推断出正确的返回类型。

有没有办法实现这一目标?

计数材料

其实有很多种方式,这里是一种方式

interface Fruits {
    names: string[];
}
interface Employees {
    ages: number[];
}

interface DataMap {
    fruits: Fruits;
    employees: Employees;
}

function getData<T extends keyof DataMap>(key: T): DataMap[T] {
if (key === "fruits") {
    // fetch data for /fruits and return it, specifying its type
    return { names: ["apple", "orange", "kiwi"] } as DataMap[T];
}

// fetch data for /employees and return it, specifying its type
    return { ages: [30, 50, 19] } as DataMap[T];
}

const fruits = getData("fruits"); // knows it's a Fruits
const fruitNames = fruits.names; // works

我们创建了一个辅助类型,用于将字符串映射到类型,并使用这个泛型来捕获 T,以便我们可以在返回类型中使用它。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

有没有办法让Typescript使用默认参数?

有没有办法强制 TypeScript 返回某种类型?

有没有办法在地图函数之外传递参数 - ReactJS - Typescript

有没有办法在TypeScript函数文档中引用参数?

有没有办法在TypeScript中递归解开函数类型?

Typescript:有没有办法在模板文字类型值中使用变量?

有没有办法在Typescript中仅提取某种接口类型的值?

有没有办法在Typescript中的包装函数中动态键入函数?

有没有办法描述TypeScript中两个参数之间的关系?

有没有办法区分 Javascript/TypeScript 中不同接口类型的对象?

有没有办法在TypeScript 2+中全局添加类型定义?

有没有办法防止TypeScript中的联合类型?

TypeScript:有没有办法检查无限嵌套数组的类型?

有没有办法在TypeScript中实例化受约束的泛型类型的实例?

有没有办法计算某个值在 TypeScript 数组中出现的次数?

在 TypeScript 中,当类型是函数的参数时,有没有办法限制 Partial<T> 类型的额外/多余属性?

有没有办法通过tslint规则在Typescript类上强制执行方法返回类型?

在 Typescript 中,有没有办法让字符串数组表现得像“或拆分类型”?

有没有办法建立返回值?

有没有办法减少多个类型的参数?

有没有办法返回作为子类的类型?

有没有办法调用部分函数

有没有办法在ListView中调用函数?

有没有办法使函数成为参数?

为什么在无法索引的类型中建立索引时Typescript不会给出错误,有没有办法使之出错呢?

有没有办法记录功能参数的参数?

有没有办法根据时间改变主题

有没有办法递归调用findMatch?

有没有办法让 eauto 正确调用 econstructor?