type Direction = 'get' | 'set'; type ConstructorFor = abstract new (...args: any[]) => T; declare const error: unique symbol; type TypeError = { [error]: M; }; type MatchWithDirection = CheckGetSet>>; type MatcherPayload = { slot: unknown; value: unknown; dir: Direction; slotName: string; valueName: string; }; type CheckSet = "set" extends T["dir"] ? T["value"] extends T["slot"] ? Else : TypeError<`Type of ${T["valueName"]} is not assignable to type of ${T["slotName"]}.`> : Else; type CheckGet = "get" extends T["dir"] ? T["slot"] extends T["value"] ? Else : TypeError<`Type of ${T["slotName"]} is not assignable to type of ${T["valueName"]}.`> : Else; type CheckGetSet = "get" | "set" extends T["dir"] ? T["slot"] extends T["value"] ? T["value"] extends T["slot"] ? Else : TypeError<`Type of ${T["slotName"]} is not equal to type of ${T["valueName"]}.`> : TypeError<`Type of ${T["slotName"]} is not equal to type of ${T["valueName"]}.`> : Else; type TypedClassDecorator = (target: TConstructor) => TConstructor | void | MatchWithDirection<{ slot: TConstructor; value: T; dir: D; slotName: "constructor"; valueName: "decorator"; }>; type TypedClassInstanceDecorator = (target: TConstructor) => TConstructor | void | MatchWithDirection<{ slot: UnsafeInstanceType; value: T; dir: D; slotName: "instance"; valueName: "decorator"; }>; type UnsafeInstanceType = T extends abstract new (...args: any[]) => infer I ? I : any; type TypedMethodDecorator = (target: TTarget, propertyKey: TKey, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void | MatchWithDirection<{ // @ts-ignore slot: TTarget[TKey]; value: T; dir: D; slotName: "method"; valueName: "decorator"; }>; type TypedParameterDecorator = (target: TTarget, prop: TKey, index: TIndex) => void | MatchWithDirection<{ slot: GetParameterType; value: T; dir: D; slotName: "parameter"; valueName: "decorator"; }>; // @ts-ignore type GetParameterType = TKey extends undefined ? ConstructorParameters[TIndex] : Parameters[TIndex]; type DecoratorPropertyKey = string | symbol | undefined; type TypedPropertyDecorator = (target: TTarget, propertyKey: TKey) => void | MatchWithDirection<{ // @ts-ignore slot: TTarget[TKey]; value: T; dir: D; slotName: "property"; valueName: "decorator"; }>; export { ConstructorFor, DecoratorPropertyKey, Direction, GetParameterType, TypedClassDecorator, TypedClassInstanceDecorator, TypedMethodDecorator, TypedParameterDecorator, TypedPropertyDecorator };