默认通用的默认值

时间:2018-04-03 12:09:32

标签: reactjs typescript inheritance abstract-class default

考虑一个通用类:

abstract class Base<T={}> {
    public getSmth(): T {
        ...
    }
}

我希望getSmth方法返回{} if T={}并且是所有其他T的抽象(需要在派生类中重写)。牛可以这样做吗?

我已尝试关注code,但问题是类C没有错误:

abstract class Base<T={}> {
    public getSmth(): T {
        return {} as T;
    }
}

class A extends Base<{}> {
    // No need to override `getSmth`
}

class B extends Base<{ x: number }> {
    public getSmth() { // Need to override as generic differes
        return {x: 8};
    }
}

class C extends Base<{ x: number }> {
    // No override for a generic parameter should be a error!
}

2 个答案:

答案 0 :(得分:1)

T的某些值不能使用方法摘要,而T的其他值也不能为摘要(即使该值是T的默认值)。如果这是一个常见的情况,更好的解决方案是使方法抽象并具有{}的默认实现。这也避免了方法中的类型断言。

abstract class Base<T> {
    public abstract getSmth(): T;
}
abstract class EmptyBase extends Base<{}> { // Implementation for {}
    public getSmth(): {} {
        return {}
    }
}

class A extends EmptyBase {
    // No need to override `getSmth` 
}

class B extends Base<{ x: number }> {
    public getSmth() { // Need to override as generic differes
        return {x: 8};
    }
}

class C extends Base<{ x: number;}> { // Must override error if you don't
}

答案 1 :(得分:0)

可以使用其他界面,但在这种情况下,您需要为每个子类明确指定它:playground

interface IBase<T={}> {
    getSmth(): T;
}

abstract class Base<T={}> {
    public getSmth() {
        return {};
    }
}

class A extends Base<{}> implements IBase<{}> {
    // No need to override `getSmth`
}

class B extends Base<{ x: number }> implements IBase<{ x: number }> {
    public getSmth() { // Need to override as generic differes
        return {x: 8};
    }
}

class C extends Base<{ x: number }> implements IBase<{ x: number }> {
    // No override for a generic parameter should be a error!
}

会出现错误:

Class 'C' incorrectly implements interface 'IBase<{ x: number; }>'.
  Types of property 'getSmth' are incompatible.
    Type '() => {}' is not assignable to type '() => { x: number; }'.
      Type '{}' is not assignable to type '{ x: number; }'.
        Property 'x' is missing in type '{}'.