【问题标题】:TypeScript: Conditional types not working with optional parametersTypeScript:条件类型不适用于可选参数
【发布时间】:2023-01-25 18:29:00
【问题描述】:

我有一个数据源,我们称它为getData(),它返回对象。有时它会返回已知类型的对象(例如PersonAnimal),但有时返回的对象具有未知的形状。

(Link to TypeScript Playground)

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
};

现在我想写一个辅助函数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。我该如何解决这个问题?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    尝试使用泛型的另一种方法是重载您的 useData 函数并指定类别:

    function useData(category: "animal"): Animal;
    function useData(category: "person"): Person;
    function useData(): any;
    function useData(category?: string): any {
      return getData();
    }
    
    const animal = useData("animal");
    //    ^ const animal: Animal
    
    const notKnown = useData();
    //    ^ const notKnown: any
    

    【讨论】:

      【解决方案2】:

      默认情况下,TS 将使用约束作为它无法推断的类型参数的类型。您可以使用 any 作为默认值来更改此设置:

      function useData<T extends keyof DataCategory = any>(category?: T) {
        const data: any = getData();
        return data as T extends undefined ? any : DataCategory[T];
      }
      

      Playground Link

      【讨论】:

        猜你喜欢
        • 2019-02-18
        • 2021-08-27
        • 2020-03-18
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        • 2018-09-06
        • 1970-01-01
        相关资源
        最近更新 更多