首页 > 解决方案 > 类构造函数类型

问题描述

我想在我的类中要求一种或另一种类型的构造函数:

const instance: MyClass = new MyClass({ digit: 5 });

... 或者 ...

const instance: MyClass = new MyClass({ letter: 'x' });

它不能同时是两个,也不能是其他一些对象。

目前我有这个:

interface MyClassConstructor {
    digit?;
    letter?;
}
interface MyClassDigit extends MyClassConstructor {
    digit: number;
}
interface MyClassLetter extends MyClassConstructor {
    letter: string;
}

class MyClass {
    constructor(obj: MyClassDigit | MyClassLetter) {
        if (obj.digit) {
            // ...
        } else if (obj.letter) {
            // ...
        }
    }
}

但我不认为这是这样做的正确方法......

标签: typescript

解决方案


我不会对您的解决方案做出太大改变。我不会拥有具有这两个属性的基本接口。我只会使用联合和in类型保护:

interface MyClassDigit {
    digit: number;
}
interface MyClassLetter {
    letter: string;
}

class MyClass {
    constructor(obj: MyClassDigit | MyClassLetter) {
        if ('digit' in obj) {
            // obj is MyClassDigit
        } else {
            // obj is MyClassLetter
        }
    }
}

如果您有更多参数并且只需要一个成员,则可以使用条件类型自动生成类型:

interface MyParams {
    digit?: number;
    letter?: string;
}
type RequireOne<T> = (keyof T) extends infer K ?
    K extends keyof T ?
    Required<Pick<T, K>> : never : never

class MyClass {
    constructor(obj: RequireOne<MyParams>) {
        if ('digit' in obj) {
            // obj has digit
        } else {
            // obj has letter 
        }
    }
}

推荐阅读