Typescript:更改某些第三方类型的定义 d.ts
Typescript: Changing the definition of some third party types d.ts
我有点不知道如何执行以下操作。
我正在尝试通过创建新文件来更改某些第三方类型的定义 thirdParty.d.ts
。
假设第三方returnsClassA
class A {
// ...
}
在我的 third-party.d.ts
文件中,我想引入两个新参数。
import * as thirdParty from 'thirdParty'
decalre module 'thirdParty' {
export interface A extends thirdParty.A {
newParam1: number
newParam2: number
}
}
然后,让我们通过添加 newParam1
和 newParam2
来覆盖 class A
class ExtendedA extends A {
newParam1 = 1
newParam2 = 2
}
所以现在一切看起来都很好。 class A 的每个实例都识别新参数。在任何函数或 class 中都可以调用 newParam1 而无需强制转换。
randomMethod() {
console.log(this.a.newParam1) // Returns 1. No need to cast (this.a as ExtendedA).newParam1 !
}
但是,由于我改变了classA的定义。而ExtendedA扩展了它。删除新参数不会产生错误。这让我担心。我正在寻找一种方法来强制 ExtendedA
对新参数进行贴标。
// This is bad :(
class ExtendedA extends A { // implements Interface will not work either
// newParam1 = 1 // Commented but there is no errors ! Which is bad
// newParam2 = 2
}
我相信修复很容易,但我真的迷路了
您正在尝试合并 class 定义。这是目前不允许的。在这里查看:https://www.typescriptlang.org/docs/handbook/declaration-merging.html#disallowed-merges
正如文档中所指出的...您可以使用 mixins 扩展第三方 class。但是你实际上会生成一个新的 class:
来自文档:
// To get started, we need a type which we'll use to extend
// other classes from. The main responsibility is to declare
// that the type being passed in is a class.
type Constructor = new (...args: any[]) => {};
// This mixin adds a scale property, with getters and setters
// for changing it with an encapsulated private property:
function Scale<TBase extends Constructor>(Base: TBase) {
return class Scaling extends Base {
// Mixins may not declare private/protected properties
// however, you can use ES2020 private fields
_scale = 1;
setScale(scale: number) {
this._scale = scale;
}
get scale(): number {
return this._scale;
}
};
}
如果您尝试创建一个新的 Class 来实现原始的,那么您期望的效果是这样的:
//========= ./third-party/third-party =========
export class A {
foo = 'foo';
}
//========= index.ts =========
import {A} from './third-party/third-party';
declare module './third-party/third-party' {
interface A {
newParam1: string;
newParam2: number
}
}
// ideally you should extend the functionality also:
// those are type safe;
// A.prototype.newParam1 = 'something';
// A.prototype.newParam2 = 20;
class B implements A {
foo='else';
newParam1='';
newParam2=20;
}
const b = new B();
console.log(b.newParam1)
但为此你需要实现所有 Class 功能或想出委托模式或其他东西。
这是一个用作游乐场的简单 repl:https://replit.com/@tiagobnobrega/module-extension#index.ts
我有点不知道如何执行以下操作。
我正在尝试通过创建新文件来更改某些第三方类型的定义 thirdParty.d.ts
。
假设第三方returnsClassA
class A {
// ...
}
在我的 third-party.d.ts
文件中,我想引入两个新参数。
import * as thirdParty from 'thirdParty'
decalre module 'thirdParty' {
export interface A extends thirdParty.A {
newParam1: number
newParam2: number
}
}
然后,让我们通过添加 newParam1
和 newParam2
class ExtendedA extends A {
newParam1 = 1
newParam2 = 2
}
所以现在一切看起来都很好。 class A 的每个实例都识别新参数。在任何函数或 class 中都可以调用 newParam1 而无需强制转换。
randomMethod() {
console.log(this.a.newParam1) // Returns 1. No need to cast (this.a as ExtendedA).newParam1 !
}
但是,由于我改变了classA的定义。而ExtendedA扩展了它。删除新参数不会产生错误。这让我担心。我正在寻找一种方法来强制 ExtendedA
对新参数进行贴标。
// This is bad :(
class ExtendedA extends A { // implements Interface will not work either
// newParam1 = 1 // Commented but there is no errors ! Which is bad
// newParam2 = 2
}
我相信修复很容易,但我真的迷路了
您正在尝试合并 class 定义。这是目前不允许的。在这里查看:https://www.typescriptlang.org/docs/handbook/declaration-merging.html#disallowed-merges
正如文档中所指出的...您可以使用 mixins 扩展第三方 class。但是你实际上会生成一个新的 class: 来自文档:
// To get started, we need a type which we'll use to extend
// other classes from. The main responsibility is to declare
// that the type being passed in is a class.
type Constructor = new (...args: any[]) => {};
// This mixin adds a scale property, with getters and setters
// for changing it with an encapsulated private property:
function Scale<TBase extends Constructor>(Base: TBase) {
return class Scaling extends Base {
// Mixins may not declare private/protected properties
// however, you can use ES2020 private fields
_scale = 1;
setScale(scale: number) {
this._scale = scale;
}
get scale(): number {
return this._scale;
}
};
}
如果您尝试创建一个新的 Class 来实现原始的,那么您期望的效果是这样的:
//========= ./third-party/third-party =========
export class A {
foo = 'foo';
}
//========= index.ts =========
import {A} from './third-party/third-party';
declare module './third-party/third-party' {
interface A {
newParam1: string;
newParam2: number
}
}
// ideally you should extend the functionality also:
// those are type safe;
// A.prototype.newParam1 = 'something';
// A.prototype.newParam2 = 20;
class B implements A {
foo='else';
newParam1='';
newParam2=20;
}
const b = new B();
console.log(b.newParam1)
但为此你需要实现所有 Class 功能或想出委托模式或其他东西。
这是一个用作游乐场的简单 repl:https://replit.com/@tiagobnobrega/module-extension#index.ts