我想实现一个可以通过不同参数推断返回类型的函数.

直接调用时正常可以推断出类型,但使用函数返回参数时,推断会不正确.

以下是我写的重新加载代码:

export interface Option {
  init?: boolean
  test?: boolean
}

function getType(): string

function getType(option: Record<string, never>): string

function getType(option: Option & { init: true }): boolean

function getType(option: Option & { init: false }): string

function getType(
  option?: Option,
): Option extends { init: true } ? boolean : string

function getType(option?: Option): boolean | string {
  if (option?.init) {
    return true
  } else {
    return 'none'
  }
}

getType() // string

getType({}) // string

getType({
  init: true,
}) // boolean

getType({
  init: false,
}) // string

getType({
  test: false,
}) // string



function useGetType(opt?: Option) {
  return getType(opt)
}


// What should be inferred here is boolean
useGetType({ init: true }) // string ??? 

推荐答案

问题是:

function getType(
  option?: Option,
): Option extends { init: true } ? boolean : string

返回类型永远不能是布尔值.为什么?因为Option永远无法扩展{init: true}.

让我们暂时忽略test字段,只考虑init字段.如果我们用const m : Option = { init :false }定义一个对象,则无法将其分配给{init : true}.因此扩展失败.

这就是为什么:

function useGetType(opt?: Option) {
  return getType(opt)
}

永远无法返回布尔值,因为这里的getType(opt)无法返回boolean.

我设置了一个小演示来给您一个 idea :

export interface Option {
  init: boolean
}
export interface WithInit {
    init : true
}

//Check this type
type T = Option extends { init: true } ? boolean : string;

const m1 : Option = Math.random() > 0.5 ? { init : true } : { init : false };
const m2 : Option = { init : true };


const n1 : WithInit = m1; //will error out
const n2 : WithInit = m2; //will error out

Playground

这可以很好地推断出来,因为这里没有任何迹象表明参数将是Option类型.

getType({
  init: true,
})

所以它匹配:

function getType(option: Option & { init: true }): boolean

Typescript相关问答推荐

如果我有对象的Typescript类型,如何使用其值的类型?

类型安全JSON解析

为什么typescript要把这个空合并转换成三元?

类型脚本泛型最初推断然后设置

Angular 信号:当输入信号改变值时,S触发取数的正确方式是什么?

Angular 错误NG0303在Angular 项目中使用app.Component.html中的NGFor

在实现自定义主题后,Angular 不会更新视图

Angular 15使用react 式表单在数组内部创建动态表单数组

CDK从可选的Lambda角色属性承担角色/复合主体中没有非空断言

如何从MAT-FORM-FIELD-MAT-SELECT中移除焦点?

React router 6(数据路由)使用数据重定向

是否可以强制静态方法将同一类型的对象返回其自己的类?

缩小对象具有某一类型的任意字段的范围

TypeScrip-根据一个参数值验证另一个参数值

TypeScrip:使用Cypress测试包含插槽的Vue3组件

编剧- Select 下拉框

类型脚本中函数重载中的类型推断问题

打字:注解`是字符串`而不是`布尔`?

使用 fp-ts 时如何使用 TypeScript 序列化任务执行?

当并非所有歧视值都已知时,如何缩小受歧视联盟的范围?