Estoy un poco perdido cómo hacer lo siguiente.
Estoy tratando de cambiar las definiciones de algunos tipos de terceros creando un nuevo archivo thirdParty.d.ts .
Supongamos que el tercero devuelve la Clase A
class A { // ... } En mi archivo third-party.d.ts , quiero introducir dos nuevos parámetros.
import * as thirdParty from 'thirdParty' decalre module 'thirdParty' { export interface A extends thirdParty.A { newParam1: number newParam2: number } } Luego, sobrescribamos la clase A agregando newParam1 y newParam2
class ExtendedA extends A { newParam1 = 1 newParam2 = 2 }Así que ahora todo se ve bien. Cada instancia de la clase A reconoce los nuevos parámetros. En cualquier función o clase es posible llamar a newParam1 sin conversión.
randomMethod() { console.log(this.a.newParam1) // Returns 1. No need to cast (this.a as ExtendedA).newParam1 ! } Sin embargo, desde que cambié la definición de clase A. Y ExtendedA la extiende. Eliminar los nuevos parámetros no generará errores. Lo cual me preocupa. Estoy buscando una forma de forzar a ExtendedA a que calcule los nuevos parámetros.
// 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 }Estoy seguro de que la solución es bastante fácil, pero estoy realmente perdido
Está intentando fusionar una definición de clase. Esto está deshabilitado por el momento. consulte aquí: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#disallowed-merges
Como se señaló en los documentos... puede extender la clase de terceros con mixins. Pero esencialmente estaría generando una nueva clase: de los documentos:
// 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; } }; }Lo que funcionará como esperas es si intentas crear una nueva Clase que implemente la original, así:
//========= ./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)Pero para eso, necesitaría implementar todas las funcionalidades de Clase A o crear un patrón de delegación o algo así.
Aquí hay una réplica simple para usar como área de juegos: https://replit.com/@tiagobnobrega/module-extension#index.ts