Skip to content

Instantly share code, notes, and snippets.

@wentout
Last active January 12, 2023 14:07
Show Gist options
  • Save wentout/80caf1a74b4feb4a54cf512f77c3f8be to your computer and use it in GitHub Desktop.
Save wentout/80caf1a74b4feb4a54cf512f77c3f8be to your computer and use it in GitHub Desktop.
TypeScript Functional Inheritance with Prototypes working
const MyConstructor: IMyConstructor = function (this: MyConstructorInstance, name: string) {
this.name = name;
} as IMyConstructor;
MyConstructor.prototype.name = 'default';
MyConstructor.prototype._char = 'default';
Object.defineProperty(MyConstructor.prototype, 'char', {
get(this: MyConstructorInstance) {
return this._char;
},
set(this: MyConstructorInstance, value: string) {
this._char = value;
}
});
interface IMyConstructor {
new (name: string): MyConstructorInstance
(name: string): never
prototype: MyConstructorInstance
}
interface MyConstructorInstance {
_char: string
name: string
char: string
}
const myConstructorInstance = new MyConstructor('ready');
// myConstructorInstance.missing = 'something'; // will handle missing field
console.log('default field', myConstructorInstance.char);
console.log('replaced field', myConstructorInstance.name);
const myConstructorInstanceProto: MyConstructorInstance = Object.getPrototypeOf(myConstructorInstance);
console.log('previous value of replaced field', myConstructorInstanceProto.name);
const MyConstructor = function (this: MyConstructorInstance, name: string) {
this.name = name;
} as IMyConstructor<MyConstructorInstance>;
(() => {
let char = 'default';
MyConstructor.prototype.name = 'default';
Object.defineProperty(MyConstructor.prototype, 'char', {
get(this: MyConstructorInstance) {
return char;
},
set(this: MyConstructorInstance, value: string) {
char = value;
}
});
})();
interface IMyConstructor <A> {
new(name: string): A
(name: string): void
prototype: A
}
type MyConstructorInstance = {
name: string
char: string
constructor: IMyConstructor<MyConstructorInstance>
}
const myConstructorInstance = new MyConstructor('ready');
// myConstructorInstance.missing = 'something'; // will handle missing field
console.log('default field', myConstructorInstance.char);
console.log('replaced field', myConstructorInstance.name);
const myConstructorInstanceProto: MyConstructorInstance = Object.getPrototypeOf(myConstructorInstance);
console.log('previous value of replaced field', myConstructorInstanceProto.name);
const MyConstructor: IMyConstructor = function (this: MyConstructorInstance, name: string) {
this.name = name;
} as IMyConstructor;
(() => {
let char = 'default';
MyConstructor.prototype.name = 'default';
Object.defineProperty(MyConstructor.prototype, 'char', {
get(this: MyConstructorInstance) {
return char;
},
set(this: MyConstructorInstance, value: string) {
char = value;
}
});
})();
interface IMyConstructor {
new(name: string): MyConstructorInstance
(name: string): never
prototype: MyConstructorInstance
}
interface MyConstructorInstance {
name: string
char: string
}
const myConstructorInstance = new MyConstructor('ready');
// myConstructorInstance.missing = 'something'; // will handle missing field
console.log('default field', myConstructorInstance.char);
console.log('replaced field', myConstructorInstance.name);
const myConstructorInstanceProto: MyConstructorInstance = Object.getPrototypeOf(myConstructorInstance);
console.log('previous value of replaced field', myConstructorInstanceProto.name);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment