type InferValue = Desc extends { get(): any; value: any } ? never : Desc extends { value: infer T } ? Record : Desc extends { get(): infer T } ? Record : never; type DefineProperty = Desc extends { writable: any; set(val: any): any; } ? never : Desc extends { writable: any; get(): any } ? never : Desc extends { writable: false } ? Readonly> : Desc extends { writable: true } ? InferValue : Readonly>; export default function defineProperty( obj: Obj, prop: Key, val: PDesc ): asserts obj is Obj & DefineProperty { Object.defineProperty(obj, prop, val); }