我有一个数据源,我们叫它getData()
,它返回对象,有时它返回已知类型的对象(例如Person
,Animal
),但有时返回的对象具有未知的形状。
(Link到TypeScriptPlayground)
type Person = { name: string; age: number };
type Animal = { species: string };
/**
* This interface stores all known object types returned by `getData()`.
* I'm storing it as an interface instead of `Person | Animal` because I
* need to store the "code" of a known type (e.g. `"person"` for `Person` type).
*/
interface DataCategory {
person: Person;
animal: Animal;
}
/** Our data source */
const getData: Person | Animal | any = () => {
return {}; // Mocked value
};
现在我想写一个helper函数useData()
来缩小getData()
的返回值。它接受keyof DataCategory
类型的可选参数并返回相应的类型。我想让这个函数返回any
如果我们不传递参数。
const person = useData("person"); // const person: Person
const animal = useData("animal"); // const animal: Animal
const notKnown = useData(); // const notKnown: any
我尝试了以下实现:
function useData<T extends keyof DataCategory>(category?: T) {
const data: any = getData();
return data as T extends undefined ? any : DataCategory[T];
}
const animal = useData("animal");
// ^ const animal: Animal
const notKnown = useData();
// ^ const notKnown: Person | Animal
// However, I want the above to be `const notKnown: any`
这不起作用,因为useData()
返回Person | Animal
而不是any
。如何解决此问题?
2条答案
按热度按时间p3rjfoxz1#
默认情况下,TS将使用约束作为它无法推断的类型参数的类型(在这种情况下,没有位置可供推断
T
),您可以通过使用any
作为默认值来更改此设置:Playground链接
正如Michael Rose在他的回答中指出的,您也可以使用重载,它们可能更容易为未来的读者所理解。
krcsximq2#
尝试使用泛型的另一种方法是重载
useData
函数并指定类别: