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 }