如何在 ts 中使用函数重载来推断参数类型

问题描述 投票:0回答:1

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

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

以下是我写的重载代码:

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 ??? 

typescript overloading
1个回答
0
投票

问题是:

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

我设置了一个小演示来给你一个想法:

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

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.