为什么打字稿抱怨我实现一个抽象类成员?

问题描述 投票:0回答:1

下面是我的自定义类型:

type KeyMap<T> = { [K in keyof T]: keyof Pick<T, K> }

其次是一个简单的接口与自定义类型的使用方法:

interface MyInterface {
    a: string;
    b: string;
}

当我喜欢的类型的变量是一类外定义,打字稿是幸福的:

const member: KeyMap<MyInterface> = {
    a: 'a',
    b: 'b'
}

但是,当我定义一个抽象类类型KeyMap的抽象成员,并试图实现它,这是行不通的。例如:

abstract class BaseClass<T> {
    protected abstract member: KeyMap<T>
    protected abstract method: () => void;
}

class DerivedClass extends BaseClass<MyInterface> {
    // TypeScript reports that property 'a' is not compatible with '"a"'
    protected member = { 
        a: 'a', 
        b: 'b'
    };

    protected method = () => console.log('');
}

直接在抽象或派生类中定义成员似乎工作。例如:

abstract class BaseClass {
    public member: KeyMap<MyInterface> = {
        a: 'a', 
        b: 'b'
    }
    protected abstract method: () => void;
}

class DerivedClass extends BaseClass {
    public derivedMember: KeyMap<MyInterface> = {
        a: 'a', 
        b: 'b'
    }

    protected method = () => console.log('');
}

一样改变构件是一个不同的类型:

abstract class BaseClass<T> {
    protected abstract member: { c: string, d: string };
    protected abstract method: () => void;
}

class DerivedClass extends BaseClass<MyInterface> {
    protected member = { 
        c: 'c', 
        d: 'd'
    };

    protected method = () => console.log('');
}

为什么打字稿报告member的派生类作为错误的执行情况时它的工作原理类外,当它不被标记为抽象的?

TypeScript Playground Link

typescript abstract-class abstract
1个回答
1
投票

类成员的类型,而不考虑什么是在基类,然后才是派生类检查与所述基类的相容性。由于成员是基于初始化值类型的,打字稿不会使用文字类型属性类型(有的只是某些地方TS不会扩大文字类型,这是不是其中之一)

最好认为你可以做的是使用该成员的显式类型注解,你已经说你在你的问题的尝试:

class DerivedClass extends BaseClass<MyInterface> {
    protected member: KeyMap<MyInterface> = { 
        a: 'a', 
        b: 'b'
    };

    protected method = () => console.log('');
}
© www.soinside.com 2019 - 2024. All rights reserved.