代码之家  ›  专栏  ›  技术社区  ›  gib

类构造函数类型

  •  0
  • gib  · 技术社区  · 6 年前

    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 回复  |  直到 6 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    6 年前

    我不会对你的解决方案有太大改变。我不会让基接口同时具有这两个属性。我只需要一个工会和一个工会 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 
            }
        }
    }
    
        2
  •  1
  •   Karol Majewski    6 年前

    超载 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