我正在设置一个从我的数据库中检索数据的函数。它接受一个键字符串作为参数,并根据键返回不同的数据类型。
我的目标是让 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] 删除。
我来说两句