首页 文章

类构造函数类型

提问于
浏览
0

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

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

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

2 回答

  • 1

    我不会改变你的解决方案 . 我没有两个属性的基接口 . 我只想使用一个union和一个 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 
            }
        }
    }
    
  • 1

    重载 constructor

    interface WithDigit {
        digit: number
    }
    
    interface WithLetter {
        letter: string
    }
    
    class MyClass {
        constructor(options: WithDigit);
        constructor(options: WithLetter);
        constructor(options: WithLetter | WithDigit) {
            if ('digit' in options) {
                /* */
            }
    
            if ('letter' in options) {
                /* */
            }
        }
    }
    

    这将确保只接受一个 .

    new MyClass({ digit: 0 });              // OK
    new MyClass({ letter: 'a' });           // OK
    new MyClass({ digit: 0, letter: 'a' }); // Error
    

相关问题