Typescript函数重载不适用于union类型的情况

时间:2018-05-07 21:06:38

标签: typescript

我无法让函数重载在Typescript中正常工作。

我有一个简单的联合类型和一个可以处理任何一种类型的函数。我已经创建了重载来独立处理它们。

type A = { type: "a", x: number }
type B = { type: "b", x: number, y: number }

type Z = A | B

function f(z: A): { x: number, y: undefined }
function f(z: B): {x: number, y: number}
function f(z: Z) {
    if (z.type === "a") {
        return {x: z.x, y: undefined}
    } else {
        return {x: z.x, y: z.y}
    }
}

它似乎也有效。

// This works
const a = f({ type: "a", x: 1 })
const b = f({ type: "b", x: 1, y: 1 })

但是,当使用消除歧义的联合类型时,它不起作用。

// Why doesn't this work?
function g(z: Z) {
    const x = f(z) 
}

// This also doesn't work.
function h<T extends Z>(z: T) {
    const x = f(z) 
}

我收到此错误:

Argument of type 'Z' is not assignable to parameter of type 'B'.
  Type 'A' is not assignable to type 'B'.
    Property 'y' is missing in type 'A'.

似乎可能是用户错误,但似乎有点像一个错误......

这是playground来检查自己尝试一下。确保打开strictNullChecks!

1 个答案:

答案 0 :(得分:2)

当编译器执行重载解析时,不会考虑重载函数实现。您必须为Z参数类型添加显式重载声明,例如:

function f(z: Z): {x: number, y: number | undefined};

完整的代码是

type A = { type: "a", x: number }
type B = { type: "b", x: number, y: number }

type Z = A | B

function f(z: A): { x: number, y: undefined }
function f(z: B): { x: number, y: number}
function f(z: Z): { x: number, y: number | undefined}
function f(z: Z) {
    if (z.type === "a") {
        return {x: z.x, y: undefined}
    } else {
        return {x: z.x, y: z.y}
    }
}

const a = f({ type: "a", x: 1 })
const b = f({ type: "b", x: 1, y: 1 })


function g(z: Z) {
    const x = f(z) 
}

function h<T extends Z>(z: T) {
    const x = f(z) 
}