指示需要哪种返回类型的typescript

sg3maiej  于 2021-09-13  发布在  Java
关注(0)|答案(2)|浏览(353)

我有一个函数可以返回两种不同的类型,我想使用一个参数指定返回:

type returnTypes = 'string' | 'object';

function getValue(returnType: returnTypes): string | Record<string, string> {
  if(returnType === 'object') {
    return { my: 'return value' }
  }
  return 'my return value';
}

interface IData {
  myObjectValue: Record<string, string>;
  myStringValue: string;
}
const data: IData = {
  myObjectValue: getValue('object'),
  myStringValue: getValue('string'),
}

打字游戏场
分配给 data 获取以下错误:
类型“string | record<string,string>”不能分配给类型“record<string,string>”。类型“string”不能分配给类型“record<string,string>”。
类型“string | record<string,string>”不可分配给类型“string”。类型“record<string,string>”不可分配给类型“string”
大概是因为typescript认为 getValue 比我的接口中定义的类型更宽。

如何根据returntype参数指示typescript,我将接收两种返回类型中的哪一种?

(或者有没有更规范的方法来实现这一点,例如只需将其分成函数,如果有,是什么/如何实现的?

esyap4oy

esyap4oy1#

typescript编译器不会根据传入的参数值推断函数的returntype。这将只在运行时进行评估。
因此,它总是假定返回的类型为 string | Record<string, string> . 您可以做的是,在接收站点使用类型Assert,告诉typescript预期的类型。

type returnTypes = 'string' | 'object';

function getValue(returnType: returnTypes): string | Record<string, string> {
  if(returnType === 'object') {
    return { my: 'return value' }
  }
  return 'my return value';
}

interface IData {
  myObjectValue: Record<string, string>;
  myStringValue: string;
}
const data: IData = {
  myObjectValue: getValue('object') as Record<string, string>,
  myStringValue: getValue('string') as string,
}

当然,这样的类型组合并不能保证它在运行时能够工作。因为如果你的 getValue 方法有一个错误,您返回一个 string 即使参数为 object ,这将导致在尝试访问时出现后续错误 myObjectvalue.my 的“最干净”解决方案可能是,定义两个不同的函数,一个返回 string 另一个返回一个 Record<string, string>

egmofgnx

egmofgnx2#

您可以使用重载。。。

function getValue(returnType: 'object'): Record<string, string>
function getValue(returnType: 'string'): string
function getValue(returnType: 'string' | 'object'): string | Record<string, string> {
  if(returnType === 'object') {
    return {my: 'return value'}
  }
  return 'my return value';
}

interface IData {
  myObjectValue: Record<string, string>;
  myStringValue: string;
}
const data: IData = {
  myObjectValue: getValue('object'),
  myStringValue: getValue('string'),
}

或具有条件返回类型的泛型,但在返回时必须在实现中进行Assert。。。

type returnTypes = 'string' | 'object';

function getValue<T extends returnTypes>(returnType: T): T extends 'string' ? string : Record<string, string> {
  if(returnType === 'object') {
    return {my: 'return value'} as any
  }
  return 'my return value' as any;
}

interface IData {
  myObjectValue: Record<string, string>;
  myStringValue: string;
}
const data: IData = {
  myObjectValue: getValue('object'),
  myStringValue: getValue('string'),
}

相关问题