Reputation: 12813
I'm filling out a module declaration of a 3rd-party JS library, and the library contains subclasses that (by Typescript's reckoning) incompatibly override methods from a parent class. There are many instances of this, but a simple example is the following:
Base class:
class Entity {
...
/**
* Test whether a given User has permission to perform some action on this Entity
* @param {User} user The User requesting creation
* @param {string} action The attempted action
* @return {boolean} Does the User have permission?
*/
can(user, action) {
...
}
}
Subclass:
class User extends Entity {
...
/**
* Test whether the User is able to perform a certain permission action. Game Master users are always allowed to
* perform every action, regardless of permissions.
*
* @param {string} permission The action to test
* @return {boolean} Does the user have the ability to perform this action?
*/
can(permission) {
...
}
}
How can I faithfully represent overridden methods like the above without tsc pointing out the obvious? Or am I going to have to "lie" in some way and misrepresent the relationship between Entity
and User
?
Upvotes: 0
Views: 219
Reputation: 12813
It seems a // @ts-ignore
is really the only option here. The other proposed solution isn't applicable to type declarations.
Upvotes: 0
Reputation: 120548
You can create a type that erases the can
property from the base Entity
type, then assign Entity
to a variable of that type.
Now you can create a new class derived from this "class"-reference variable.
This breaks polymorphism (as did the original developer). It's awful. Don't do this. Bite the bullet and refactor your mess.
class Entity {
can(user: string, action: string) {
console.log(user, action)
}
}
type PartialEntity = new () => { [P in Exclude<keyof Entity, 'can'>]: Entity[P] }
const EntityNoCan: PartialEntity = Entity;
class User extends EntityNoCan {
can(permission: number) {
console.log(permission)
}
}
Upvotes: 2