interface Props { name: string } interface Core { id: string } interface Instance extends Props, Core {} const defaults: Props = { name: 'Spot', } const core: Core = { id: '0', } class ClassInstance implements Instance { id = '0' name = 'Spot' constructor( props: Partial & { [K in keyof T]: K extends keyof Core ? never : T[K] } ) { Object.assign(this, props) } } interface InstanceConstructor { new ( props: Partial & { [K in keyof T]: K extends keyof Core ? never : T[K] } ): Instance } function makeInstance( props: Partial & { [K in keyof T]: K extends keyof Core ? never : T[K] } & ThisType ) { return new ClassInstance({ ...defaults, ...props, ...core }) } function getInstance( props: Partial & { [K in keyof T]: K extends keyof Core ? never : T[K] } ) { return { ...defaults, ...props, ...core } } const instance = getInstance({ name: 'Steve', age: 93, wag(this: Instance) { return this.name }, }) interface AnimalProps { name: string greet(this: Animal, name: string): string } interface AnimalCore { id: string sleep(this: Animal): void } interface Animal extends AnimalProps, AnimalCore {} const getAnimal = ( props: Partial & { [K in keyof T]: K extends keyof AnimalCore ? never : T[K] } ): Animal & T => { return { // Defaults name: 'Animal', greet(name) { return 'Hey ' + name }, // Overrides ...props, // Core id: 'hi', sleep() {}, } } const dog = getAnimal({ name: 'doggo', greet(name) { return 'Woof ' + this.name }, wag() { return 'wagging...' }, }) dog.greet('steve') dog.wag() dog.sleep() class ShapeTest {} const shapeTest = new ShapeTest() export default shapeTest type Greet = (name: string) => string const greet: Greet = (name: string | number) => { return 'hello ' + name }