Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark internal APIs with @internal JSDoc tag #104

Merged
merged 6 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 20 additions & 18 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
*
* **_Unexpected failure_**? For a more permissive but less performant
* check that accommodates for equivalent intersection types,
* use {@linkcode branded `.branded.toEqualTypeOf()`}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing The documentation for details}.
* use {@linkcode branded | .branded.toEqualTypeOf()}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}.
*
* @example
* <caption>Using generic type argument syntax</caption>
Expand Down Expand Up @@ -86,8 +86,8 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
*
* **_Unexpected failure_**? For a more permissive but less performant
* check that accommodates for equivalent intersection types,
* use {@linkcode branded `.branded.toEqualTypeOf()`}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing The documentation for details}.
* use {@linkcode branded | .branded.toEqualTypeOf()}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}.
*
* @example
* <caption>Using generic type argument syntax</caption>
Expand Down Expand Up @@ -119,7 +119,7 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {

toMatchTypeOf: {
/**
* A less strict version of {@linkcode toEqualTypeOf `.toEqualTypeOf()`}
* A less strict version of {@linkcode toEqualTypeOf | .toEqualTypeOf()}
* that allows for extra properties.
* This is roughly equivalent to an `extends` constraint
* in a function type argument.
Expand All @@ -146,7 +146,7 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
): true

/**
* A less strict version of {@linkcode toEqualTypeOf `.toEqualTypeOf()`}
* A less strict version of {@linkcode toEqualTypeOf | .toEqualTypeOf()}
* that allows for extra properties.
* This is roughly equivalent to an `extends` constraint
* in a function type argument.
Expand Down Expand Up @@ -205,7 +205,7 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {

/**
* Intersection types can cause issues with
* {@linkcode toEqualTypeOf `.toEqualTypeOf()`}:
* {@linkcode toEqualTypeOf | .toEqualTypeOf()}:
* ```ts
* // ❌ The following line doesn't compile, even though the types are arguably the same.
* expectTypeOf<{ a: 1 } & { b: 2 }>().toEqualTypeOf<{ a: 1; b: 2 }>()
Expand All @@ -216,7 +216,7 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
* __Note__: This comes at a performance cost, and can cause the compiler
* to 'give up' if used with excessively deep types, so use sparingly.
*
* @see {@link https://github.com/mmkal/expect-type/pull/21 Reference}
* @see {@link https://github.com/mmkal/expect-type/pull/21 | Reference}
*/
branded: {
/**
Expand All @@ -228,8 +228,8 @@ export interface PositiveExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
*
* **_Unexpected failure_**? For a more permissive but less performant
* check that accommodates for equivalent intersection types,
* use {@linkcode PositiveExpectTypeOf.branded `.branded.toEqualTypeOf()`}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing The documentation for details}.
* use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}.
*
* @example
* <caption>Using generic type argument syntax</caption>
Expand Down Expand Up @@ -274,8 +274,8 @@ export interface NegativeExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
*
* **_Unexpected failure_**? For a more permissive but less performant
* check that accommodates for equivalent intersection types,
* use {@linkcode PositiveExpectTypeOf.branded `.branded.toEqualTypeOf()`}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing The documentation for details}.
* use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}.
*
* @example
* <caption>Using generic type argument syntax</caption>
Expand Down Expand Up @@ -311,8 +311,8 @@ export interface NegativeExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
*
* **_Unexpected failure_**? For a more permissive but less performant
* check that accommodates for equivalent intersection types,
* use {@linkcode PositiveExpectTypeOf.branded `.branded.toEqualTypeOf()`}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing The documentation for details}.
* use {@linkcode PositiveExpectTypeOf.branded | .branded.toEqualTypeOf()}.
* @see {@link https://github.com/mmkal/expect-type#why-is-my-assertion-failing | The documentation for details}.
*
* @example
* <caption>Using generic type argument syntax</caption>
Expand All @@ -339,7 +339,7 @@ export interface NegativeExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {
toMatchTypeOf: {
/**
* A less strict version of
* {@linkcode PositiveExpectTypeOf.toEqualTypeOf `.toEqualTypeOf()`}
* {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()}
* that allows for extra properties.
* This is roughly equivalent to an `extends` constraint
* in a function type argument.
Expand Down Expand Up @@ -367,7 +367,7 @@ export interface NegativeExpectTypeOf<Actual> extends BaseExpectTypeOf<Actual, {

/**
* A less strict version of
* {@linkcode PositiveExpectTypeOf.toEqualTypeOf `.toEqualTypeOf()`}
* {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()}
* that allows for extra properties.
* This is roughly equivalent to an `extends` constraint
* in a function type argument.
Expand Down Expand Up @@ -502,7 +502,7 @@ export interface BaseExpectTypeOf<Actual, Options extends {positive: boolean}> {
* Checks whether a function is callable with the given parameters.
*
* __Note__: You cannot negate this assertion with
* {@linkcode PositiveExpectTypeOf.not `.not`}, you need to use
* {@linkcode PositiveExpectTypeOf.not | .not}, you need to use
* `ts-expect-error` instead.
*
* @example
Expand All @@ -514,7 +514,7 @@ export interface BaseExpectTypeOf<Actual, Options extends {positive: boolean}> {
*
* __Known Limitation__: This assertion will likely fail if you try to use it
* with a generic function or an overload.
* @see {@link https://github.com/mmkal/expect-type/issues/50 This issue} for an example and a workaround.
* @see {@link https://github.com/mmkal/expect-type/issues/50 | This issue} for an example and a workaround.
*
* @param args - The arguments to check for callability.
* @returns `true`.
Expand Down Expand Up @@ -855,6 +855,7 @@ export type _ExpectTypeOf = {
* form of a reference or generic type parameter.
*
* @example
* ```ts
* import { foo, bar } from '../foo'
* import { expectTypeOf } from 'expect-type'
*
Expand All @@ -867,6 +868,7 @@ export type _ExpectTypeOf = {
* expectTypeOf(bar).parameter(0).toBeString()
* expectTypeOf(bar).returns.not.toBeAny()
* })
* ```
*
* @description
* See the [full docs](https://npmjs.com/package/expect-type#documentation) for lots more examples.
Expand Down
49 changes: 49 additions & 0 deletions src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,48 +51,97 @@ export type MismatchInfo<Actual, Expected> =
? Actual
: `Expected: ${PrintType<Expected>}, Actual: ${PrintType<Exclude<Actual, Expected>>}`

/**
* @internal
*/
const inverted = Symbol('inverted')

/**
* @internal
*/
type Inverted<T> = {[inverted]: T}

/**
* @internal
*/
const expectNull = Symbol('expectNull')
export type ExpectNull<T> = {[expectNull]: T; result: ExtendsExcludingAnyOrNever<T, null>}

/**
* @internal
*/
const expectUndefined = Symbol('expectUndefined')
export type ExpectUndefined<T> = {[expectUndefined]: T; result: ExtendsExcludingAnyOrNever<T, undefined>}

/**
* @internal
*/
const expectNumber = Symbol('expectNumber')
export type ExpectNumber<T> = {[expectNumber]: T; result: ExtendsExcludingAnyOrNever<T, number>}

/**
* @internal
*/
const expectString = Symbol('expectString')
export type ExpectString<T> = {[expectString]: T; result: ExtendsExcludingAnyOrNever<T, string>}

/**
* @internal
*/
const expectBoolean = Symbol('expectBoolean')
export type ExpectBoolean<T> = {[expectBoolean]: T; result: ExtendsExcludingAnyOrNever<T, boolean>}

/**
* @internal
*/
const expectVoid = Symbol('expectVoid')
export type ExpectVoid<T> = {[expectVoid]: T; result: ExtendsExcludingAnyOrNever<T, void>}

/**
* @internal
*/
const expectFunction = Symbol('expectFunction')
export type ExpectFunction<T> = {[expectFunction]: T; result: ExtendsExcludingAnyOrNever<T, (...args: any[]) => any>}

/**
* @internal
*/
const expectObject = Symbol('expectObject')
export type ExpectObject<T> = {[expectObject]: T; result: ExtendsExcludingAnyOrNever<T, object>}

/**
* @internal
*/
const expectArray = Symbol('expectArray')
export type ExpectArray<T> = {[expectArray]: T; result: ExtendsExcludingAnyOrNever<T, any[]>}

/**
* @internal
*/
const expectSymbol = Symbol('expectSymbol')
export type ExpectSymbol<T> = {[expectSymbol]: T; result: ExtendsExcludingAnyOrNever<T, symbol>}

/**
* @internal
*/
const expectAny = Symbol('expectAny')
export type ExpectAny<T> = {[expectAny]: T; result: IsAny<T>}

/**
* @internal
*/
const expectUnknown = Symbol('expectUnknown')
export type ExpectUnknown<T> = {[expectUnknown]: T; result: IsUnknown<T>}

/**
* @internal
*/
const expectNever = Symbol('expectNever')
export type ExpectNever<T> = {[expectNever]: T; result: IsNever<T>}

/**
* @internal
*/
const expectNullable = Symbol('expectNullable')
export type ExpectNullable<T> = {[expectNullable]: T; result: Not<StrictEqualUsingBranding<T, NonNullable<T>>>}

Expand Down
14 changes: 8 additions & 6 deletions src/overloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export type UnknownFunction = (...args: unknown[]) => unknown
* This is useful because older versions of TypeScript end up with
* 9 "useless" overloads and one real one for parameterless/generic functions.
*
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 Related}
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related}
*/
export type IsUselessOverloadInfo<FunctionType> = StrictEqualUsingTSInternalIdenticalToOperator<
FunctionType,
Expand All @@ -53,7 +53,7 @@ export type Tuplify<Union> = Union extends infer X ? [X] : never
* for parameterless functions. To do this we use
* {@linkcode IsUselessOverloadInfo} to remove useless overloads.
*
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 Related}
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related}
*/
export type TSPre53OverloadsInfoUnion<FunctionType> =
// first, pointlessly wrap the overload variants in a 1-tuple, then infer them as `Tup` - this helps TypeScript isolate out the overload variants
Expand Down Expand Up @@ -97,7 +97,7 @@ export type DecreasingOverloadsInfoUnion<F> = F extends {(...args: infer A1): in
/**
* Get a union of overload variants for a function {@linkcode FunctionType}.
* Does a check for whether we can do the one-shot
* 10-overload matcher (which works for ts>5.3), and if not,
* 10-overload matcher (which works for ts\>5.3), and if not,
* falls back to the more complicated utility.
*/
export type OverloadsInfoUnion<FunctionType> =
Expand Down Expand Up @@ -181,7 +181,7 @@ export type IsUselessConstructorOverloadInfo<FunctionType> = StrictEqualUsingTSI
* for parameterless constructors. To do this we use
* {@linkcode IsUselessConstructorOverloadInfo} to remove useless overloads.
*
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 Related}
* @see {@link https://github.com/microsoft/TypeScript/issues/28867 | Related}
*/
export type TSPre53ConstructorOverloadsInfoUnion<ConstructorType> =
// first, pointlessly wrap the overload variants in a 1-tuple, then infer them as `Tup` - this helps TypeScript isolate out the overload variants
Expand Down Expand Up @@ -225,7 +225,7 @@ export type DecreasingConstructorOverloadsInfoUnion<ConstructorType> = Construct
/**
* Get a union of overload variants for a constructor
* {@linkcode ConstructorType}. Does a check for whether we can do the
* one-shot 10-overload matcher (which works for ts>5.3), and if not,
* one-shot 10-overload matcher (which works for ts\>5.3), and if not,
* falls back to the more complicated utility.
*/
export type ConstructorOverloadsUnion<ConstructorType> =
Expand All @@ -234,7 +234,9 @@ export type ConstructorOverloadsUnion<ConstructorType> =
? TSPre53ConstructorOverloadsInfoUnion<ConstructorType>
: TSPost53ConstructorOverloadsInfoUnion<ConstructorType>

/** Allows inferring any constructor using the `infer` keyword. */
/**
* Allows inferring any constructor using the `infer` keyword.
*/
// This *looks* fairly pointless but if you try to use `new (...args: any) => any` directly, TypeScript will not infer the constructor type correctly.
export type InferConstructor<ConstructorType extends new (...args: any) => any> = ConstructorType

Expand Down
26 changes: 22 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ export type Eq<Left extends boolean, Right extends boolean> = Left extends true
*/
export type Xor<Types extends [boolean, boolean]> = Not<Eq<Types[0], Types[1]>>

/**
* @internal
*/
const secret = Symbol('secret')

/**
* @internal
*/
type Secret = typeof secret

/**
Expand Down Expand Up @@ -103,6 +110,8 @@ export type ReadonlyKeys<T> = Extract<{
// prettier-ignore
/**
* Determines if two types, are equivalent in a `readonly` manner.
*
* @internal
*/
type ReadonlyEquivalent<X, Y> = Extends<
(<T>() => T extends X ? true : false), (<T>() => T extends Y ? true : false)
Expand All @@ -123,7 +132,7 @@ export type ExtendsExcludingAnyOrNever<Left, Right> = IsAny<Left> extends true ?
* Checks if two types are strictly equal using
* the TypeScript internal identical-to operator.
*
* @see {@link https://github.com/microsoft/TypeScript/issues/55188#issuecomment-1656328122 much history}
* @see {@link https://github.com/microsoft/TypeScript/issues/55188#issuecomment-1656328122 | much history}
*/
export type StrictEqualUsingTSInternalIdenticalToOperator<L, R> =
(<T>() => T extends (L & T) | T ? true : false) extends <T>() => T extends (R & T) | T ? true : false
Expand All @@ -140,14 +149,23 @@ export type StrictEqualUsingTSInternalIdenticalToOperator<L, R> =
*/
export type MutuallyExtends<Left, Right> = And<[Extends<Left, Right>, Extends<Right, Left>]>

/**
* @internal
*/
const mismatch = Symbol('mismatch')

/**
* @internal
*/
type Mismatch = {[mismatch]: 'mismatch'}

/**
* A type which should match anything passed as a value but *doesn't*
* match {@linkcode Mismatch}. It helps TypeScript select the right overload
* for {@linkcode PositiveExpectTypeOf.toEqualTypeOf `.toEqualTypeOf()`} and
* {@linkcode PositiveExpectTypeOf.toMatchTypeOf `.toMatchTypeOf()`}.
* for {@linkcode PositiveExpectTypeOf.toEqualTypeOf | .toEqualTypeOf()} and
* {@linkcode PositiveExpectTypeOf.toMatchTypeOf | .toMatchTypeOf()}.
*
* @internal
*/
const avalue = Symbol('avalue')

Expand Down Expand Up @@ -179,7 +197,7 @@ export interface ExpectTypeOfOptions {

/**
* Convert a union to an intersection.
* `A | B | C` -> `A & B & C`
* `A | B | C` -\> `A & B & C`
*/
export type UnionToIntersection<Union> = (Union extends any ? (distributedUnion: Union) => void : never) extends (
mergedIntersection: infer Intersection,
Expand Down