如何从打字稿中预定义的基类中删除动态键?

时间:2019-02-20 09:56:49

标签: typescript

假设我有我的第三方基类,如以下示例所示:

export class Base {
    [k: string]: any;
    foo(): number;
    bar(): number;
};

那我需要继承它,但是我不想在对象中使用动态键,这可能吗?

例如,我希望能够进行类型安全的操作,例如:

class Child extends Base {
    // remove all dynamic keys
    // well dont actually delete it, just make it non-accessible from my ts-code.
    bzx(): number { return 3; }
}

const b = new Child();
b.foo() // OK;
b.bzx() // OK;
b.baz() // not allowed;

我尝试按照https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.htmlFunctionProperties<T>的示例进行操作

但是如果T[k: string]:any,它似乎又失败了;

已解决: 所以是的,最后,我接受了建议的答案,最后我复制了基类的整个数据,除了: [k: string]: any

并使其成为接口而不是类。

是的,这个想法是这样的:

import { Base } from 'Base';
import { IBase } from 'my/own/custom/IBase.ts'
class Child extends (Base as (new () => IBase)){ ... }

好吧,我相信它在实际代码中会稍微好一点,因为涉及了mixins,所以它更接近:

function mix<C extends IBase>(base: Constructor<IBase>){ 
   return class extends base { .... }
}

class Child extends mix(Base){ ... }

1 个答案:

答案 0 :(得分:2)

不幸的是,您不能获得类型的非动态部分中的键。 keyof将始终为string返回Base。但是,我们可以使用Pick来获取非动态键的属性。如果您不介意拼写所有键(并且我知道那是很大的话),则可以执行以下操作:

export declare class Base {
    [k: string]: any;
    foo(): number;
    bar(): number;
};

const SafeBase = Base as (new () => Pick<Base, 'foo' | 'bar'>)
class Child extends SafeBase {
    // remove all dynamic keys
    // well dont actually delete it, just make it non-accessible from my ts-code.
    bzx(): number { return 3; }
}

const b = new Child();
b.foo() // OK;
b.bzx() // OK;
b.baz() // not allowed;