Skip to content

Commit

Permalink
feat(types): ClassDecorator, MethodDecorator
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Aug 12, 2023
1 parent 01f8e6c commit 514e5fc
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 2 deletions.
1 change: 1 addition & 0 deletions .eslintrc.base.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ const config = {
'@typescript-eslint/consistent-indexed-object-style': 0,
'@typescript-eslint/no-base-to-string': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-invalid-void-type': 0,
'@typescript-eslint/no-unused-expressions': 0,
'@typescript-eslint/prefer-ts-expect-error': 0,
'@typescript-eslint/require-await': 0,
Expand Down
6 changes: 6 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ const config = {
'@typescript-eslint/ban-types': 0
}
},
{
files: ['src/types/decorator-class.ts', 'src/types/decorator-method.ts'],
rules: {
'@typescript-eslint/no-invalid-void-type': 0
}
},
{
files: ['src/utils/__tests__/ksort.spec.ts'],
rules: {
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/property-descriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ interface PropertyDescriptor<T = any> {
* being assigned to the property) and with `this` set to the object through
* which the property is assigned.
*
* @param {T} v - Value being assigned to property
* @param {T} value - Value being assigned to property
* @return {void} Nothing when complete
*/
set?(v: T): void
set?(value: T): void

/**
* Value associated with the property.
Expand Down
20 changes: 20 additions & 0 deletions src/types/__tests__/decorator-class.spec-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @file Type Tests - ClassDecorator
* @module tutils/types/tests/unit-d/ClassDecorator
*/

import type Vehicle from '#fixtures/types/vehicle'
import type Class from '../class'
import type TestSubject from '../decorator-class'

describe('unit-d:types/ClassDecorator', () => {
type T = Class<Vehicle, [vin: Vehicle['vin']]>

it('should be callable with [T]', () => {
expectTypeOf<TestSubject<T>>().parameters.toEqualTypeOf<[T]>()
})

it('should return T | void', () => {
expectTypeOf<TestSubject<T>>().returns.toEqualTypeOf<T | void>()
})
})
32 changes: 32 additions & 0 deletions src/types/__tests__/decorator-method.spec-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @file Type Tests - MethodDecorator
* @module tutils/types/tests/unit-d/MethodDecorator
*/

import type Vehicle from '#fixtures/types/vehicle'
import type { PropertyDescriptor } from '#src/interfaces'
import type Class from '../class'
import type TestSubject from '../decorator-method'
import type Fn from '../fn'
import type OwnPropertyKey from '../property-key-own'

describe('unit-d:types/MethodDecorator', () => {
type T = Fn<[vin: Vehicle['vin']], Vehicle>
type U = Class<Vehicle, [vin: Vehicle['vin']]>

it('should be callable with [U, OwnPropertyKey, PropertyDescriptor<T>]', () => {
// Arrange
type Expect = [U, OwnPropertyKey, PropertyDescriptor<T>]

// Expect
expectTypeOf<TestSubject<T, U>>().parameters.toEqualTypeOf<Expect>()
})

it('should return PropertyDescriptor<T> | void', () => {
// Arrange
type Expect = PropertyDescriptor<T> | void

// Expect
expectTypeOf<TestSubject<T>>().returns.toEqualTypeOf<Expect>()
})
})
23 changes: 23 additions & 0 deletions src/types/decorator-class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @file Type Definitions - ClassDecorator
* @module tutils/types/ClassDecorator
*/

import type Constructor from './constructor'
import type AbstractConstructor from './constructor-abstract'

/**
* A class decorator.
*
* @see https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators
*
* @template T - Class type
*
* @param {T} target - Class declaration
* @return {T | void} Class declaration or `undefined`
*/
type ClassDecorator<T extends AbstractConstructor<any> = Constructor<any>> = (
target: T
) => T | void

export type { ClassDecorator as default }
34 changes: 34 additions & 0 deletions src/types/decorator-method.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @file Type Definitions - MethodDecorator
* @module tutils/types/MethodDecorator
*/

import type { PropertyDescriptor } from '#src/interfaces'
import type DecoratorTarget from './decorator-target'
import type Fn from './fn'
import type OwnPropertyKey from './property-key-own'

/**
* A method decorator.
*
* @see {@linkcode DecoratorTarget}
* @see https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators
*
* @template T - Property descriptor value type
* @template U - Class constructor or instance type
*
* @param {U} target - Class declaration or prototype
* @param {OwnPropertyKey} key - Method name
* @param {PropertyDescriptor<T>} descriptor - Property descriptor for `key`
* @return {PropertyDescriptor<T> | void} Property descriptor or `undefined`
*/
type MethodDecorator<
T extends Fn = Fn,
U extends DecoratorTarget = DecoratorTarget
> = (
target: U,
key: OwnPropertyKey,
descriptor: PropertyDescriptor<T>
) => PropertyDescriptor<T> | void

export type { MethodDecorator as default }
2 changes: 2 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export type { default as Constructor } from './constructor'
export type { default as AbstractConstructor } from './constructor-abstract'
export type { default as ContinuousValue } from './continuous-value'
export type { default as Crush } from './crush'
export type { default as ClassDecorator } from './decorator-class'
export type { default as MethodDecorator } from './decorator-method'
export type { default as DecoratorTarget } from './decorator-target'
export type { default as Defaults } from './defaults'
export type { default as Digit } from './digit'
Expand Down

0 comments on commit 514e5fc

Please sign in to comment.