网站搜索

在 TypeScript 中,我如何根据参数确定函数的返回类型?


在 TypeScript 中,我想根据函数的参数来确定其返回类型。在下面的示例中,如果 getPropsForComponentKey 被调用时传入的参数类型是 ComponentKey.A,那么它的返回类型应该是 AProps。我应该能够使用控制流分析来防止返回不兼容类型的值。然而,我不确定如何描述这个函数的类型,以便在传入 'A' 时期望返回 AProps。

我尝试使用一个泛型类型 T,并用它来索引一个索引访问类型 PropTypesForComponentKey,以便返回类型将根据传入函数的内容解析为 AProps 或 BProps。编译器错误表明 AProps 不能赋值给 PropTypesForComponentKey[T]。

TS 游乐场

type AProps = {
  value: number;
}

type BProps = {
  description: string;
}

enum ComponentKey {
  A = 'A',
  B = 'B',
}

type PropTypesForComponentKey  = {
  [ComponentKey.A]: AProps;
  [ComponentKey.B]: BProps;
}

// this object enforces the mapping between key and value types
const propsForComponentKey: PropTypesForComponentKey = {
  [ComponentKey.A]: { value: 3 },
  [ComponentKey.B]: { description: 'foo' },
}

// we know that aProp is of type AProps when we use 'A' as an index into propsForComponentKey
const aProp = propsForComponentKey['A'];

// How do I enforce the return type of this function?
function getPropsForComponentKey<T extends ComponentKey>(componentKey: T): null | PropTypesForComponentKey[T] {
  switch(componentKey) {
    case ComponentKey.A:
      return { value:  3 } as AProps;
    case ComponentKey.B:
      return { description: 'foo' };
  }
  return null;
}

答案#1

我没有通过控制流分析实现这种行为。不过,你可以通过使用函数重载得到相同的结果。这种方法有点冗长,但能完成工作。

function getPropsForComponentKey(componentKey: ComponentKey.A): AProps
function getPropsForComponentKey(componentKey: ComponentKey.B): BProps
function getPropsForComponentKey(componentKey: string): null
function getPropsForComponentKey(componentKey: ComponentKey | string): null | AProps | BProps {
  switch(componentKey) {
    case ComponentKey.A:
      return { value:  3 } as AProps
      
    case ComponentKey.B:
      return { description: 'foo' } as BProps;
  }
  return null;
}

操场