Skip to content

Commit

Permalink
Add AbstractClass type (sindresorhus#559)
Browse files Browse the repository at this point in the history
  • Loading branch information
rayrw authored and orimiles5 committed Mar 11, 2023
1 parent d7a1d0f commit dfb46ad
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Click the type names for complete docs.
- [`Primitive`](source/primitive.d.ts) - Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive).
- [`Class`](source/basic.d.ts) - Matches a [`class`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
- [`Constructor`](source/basic.d.ts) - Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes).
- [`AbstractClass`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes).
- [`AbstractConstructor`](source/basic.d.ts) - Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor.
- [`TypedArray`](source/typed-array.d.ts) - Matches any [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray), like `Uint8Array` or `Float64Array`.
- [`ObservableLike`](source/observable-like.d.ts) - Matches a value that is like an [Observable](https://github.com/tc39/proposal-observable).

Expand Down
14 changes: 14 additions & 0 deletions source/basic.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ Matches a [`class` constructor](https://developer.mozilla.org/en-US/docs/Web/Jav
*/
export type Constructor<T, Arguments extends unknown[] = any[]> = new(...arguments_: Arguments) => T;

/**
Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/classes.html#abstract-classes).
@category Class
*/
export type AbstractClass<T, Arguments extends unknown[] = any[]> = AbstractConstructor<T, Arguments> & {prototype: T};

/**
Matches an [`abstract class`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-2.html#abstract-construct-signatures) constructor.
@category Class
*/
export type AbstractConstructor<T, Arguments extends unknown[] = any[]> = abstract new(...arguments_: Arguments) => T;

/**
Matches a JSON object.
Expand Down
40 changes: 40 additions & 0 deletions test-d/abstract-class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {expectAssignable, expectError} from 'tsd';
import type {AbstractConstructor, AbstractClass} from '../index';

abstract class Foo {
abstract fooMethod(): void;
}

abstract class Bar {
abstract barMethod(): void;
}

function functionRecevingAbsClass<T>(cls: AbstractClass<T>) {
return cls;
}

function withBar<T extends AbstractConstructor<object>>(Ctor: T) {
abstract class ExtendedBar extends Ctor {
// eslint-disable-next-line @typescript-eslint/no-empty-function
extendedBarMethod() {}
}
return ExtendedBar;
}

function assertWithBar() {
// This lacks `barMethod`.
// @ts-expect-error
class WrongConcreteExtendedBar extends withBar(Bar) {}

// This should be alright since `barMethod` is implemented.
class CorrectConcreteExtendedBar extends withBar(Bar) {
// eslint-disable-next-line @typescript-eslint/no-empty-function
barMethod() {}
}
expectAssignable(functionRecevingAbsClass<Bar>(withBar(Bar)));
expectAssignable(functionRecevingAbsClass<Bar>(CorrectConcreteExtendedBar));
}

expectAssignable(functionRecevingAbsClass(Foo));
expectError(functionRecevingAbsClass<Bar>(Foo));
assertWithBar();

0 comments on commit dfb46ad

Please sign in to comment.