简体   繁体   English

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

[英]Typescript function overloads not working for the union type case

I'm having trouble getting function overloads to work properly in Typescript. 我无法让函数重载在Typescript中正常工作。

I have a simple union type and a function that can handle either type. 我有一个简单的联合类型和一个可以处理任何一种类型的函数。 I've created overloads to handle each of them independently. 我创建了重载来分别处理每个重载。

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

It appears to work as well. 它似乎也可以工作。

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

However, when it comes to using it with a disambiguated union type, it doesn't work. 但是,当使用带有明确的联合体类型的方法时,它将不起作用。

// 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) 
}

I get this error: 我收到此错误:

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'.

Seems like it might user error, but also seems kind of like a bug... 似乎它可能是用户错误,但似乎也像个错误...

Here's a playground to check try it yourself. 这是一个游乐场 ,您可以自己尝试一下。 Make sure to turn strictNullChecks on! 确保打开strictNullChecks!

Overloaded function implementation is not taken into account when compiler does overload resolution. 编译器执行重载解析时,不会考虑重载函数的实现。 You have to add an explicit overload declaration for Z argument type, for exapmle like this: 您必须为Z参数类型添加一个显式的重载声明,例如:

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

The complete code is 完整的代码是

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) 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM