TypeScript:联合类型的对象,而不是在每一侧定义整个类型

时间:2018-03-08 22:05:29

标签: typescript

我正在将前端Java转换为TypeScript,我正在处理方法重载。

我想写这样的类型

const person = (info: {name:string, age:number} | {man:boolean}): void => {
    if (typeof info.man === "boolean") {
        console.log("man is defined", info.man);
    } else {
        console.log(info.name, info.age);
    }
}

person({name:"Joe", age:25});
person({ man: false});

但我喜欢这样才能让TypeScript感到高兴

const person = (info: {name:string, age:number, man?:undefined} 
  | {name?:string, age?:number, man:boolean}): void => {
    if (typeof info.man === "boolean") {
        console.log("man is defined", info.man);
    } else {
        console.log(info.name, info.age);
    }
}

person({name:"Joe", age:25});
person({ man: false});

我希望有一种更漂亮的方法来定义类型以使其更具可读性

2 个答案:

答案 0 :(得分:2)

TypeScript实际上通过指定多个函数签名来支持方法重载。最后一个签名是实际的实现,将由编译器隐藏。

function person(info: { name: string, age: number }): void;
function person(info: { man: boolean }): void;
function person(info: any) {
    if (typeof info.man === "boolean") {
        console.log("man is defined", info.man);
    } else {
        console.log(info.name, info.age);
    }
}

如果您希望指定箭头功能,可以在单独的类型中定义重载。

type Person = {
    (info: { man: boolean }): void,
    (info: { name: string, age: number}): void,
}
const person: Person = (info: any) => {
    if (typeof info.man === "boolean") {
        console.log("man is defined", info.man);
    } else {
        console.log(info.name, info.age);
    }
}

答案 1 :(得分:2)

你可以在这里使用默认函数重载,不完全像你想要的例子,但更具可读性:

function person(info: { man: boolean }): void;
function person(info: { name: string, age: number }): void;
function person(info: any): void {
    if (typeof info.man === "boolean") {
        console.log("man is defined", info.man);
    } else {
        console.log(info.name, info.age);
    }
}

这种方式的工作方式是,编译器隐藏了实现的签名,并使用重载的签名进行类型检查。