import type {IsNever} from './is-never.d.ts'; import type {IsAny} from './is-any.d.ts'; import type {ApplyDefaultOptions} from './internal/object.d.ts'; import type {And} from './and.d.ts'; import type {Or} from './or.d.ts'; import type {IsUnknown} from './is-unknown.d.ts'; import type {OrAll} from './or-all.d.ts'; export type ExtendsStrictOptions = { /** Whether to distribute over unions. @default false @example ``` import type {ExtendsStrict} from 'type-fest'; type T1 = ExtendsStrict; //=> boolean type T2 = ExtendsStrict; //=> false ``` */ distributiveUnions?: boolean; /** Whether `never` extends every other type. When enabled, `never` is not treated as a bottom type and only extends itself (or `any` / `unknown`). @default true @example ``` import type {ExtendsStrict} from 'type-fest'; type T1 = ExtendsStrict; //=> false type T2 = ExtendsStrict; //=> true type T3 = ExtendsStrict; //=> true type T4 = ExtendsStrict; //=> true type T5 = ExtendsStrict; //=> true ``` Note: This option only has an effect when checking assignability from `never` (`ExtendsStrict`), and not when checking assignability to `never` (`ExtendsStrict<..., never>`). */ strictNever?: boolean; /** Whether `any` extends every other type. When enabled, `any` does not extend every other type, it only extends itself (or `unknown`). @default false @example ``` import type {ExtendsStrict} from 'type-fest'; type T1 = ExtendsStrict; //=> false type T2 = ExtendsStrict; //=> true type T3 = ExtendsStrict; //=> true type T4 = ExtendsStrict; //=> true ``` Note: If `strictAny` is `false` and `distributiveUnions` is `true`, then `any` would distribute and the result would be the `boolean` type, except when checking assignability to `any` or `unknown`. @example ``` import type {ExtendsStrict} from 'type-fest'; type T1 = ExtendsStrict; //=> boolean type T2 = ExtendsStrict; //=> true type T3 = ExtendsStrict; //=> true ``` Note: This option only has an effect when checking assignability from `any` (`ExtendsStrict`), and not when checking assignability to `any` (`ExtendsStrict<..., any>`). */ strictAny?: boolean; }; type DefaultExtendsStrictOptions = { distributiveUnions: false; strictNever: true; strictAny: false; }; /** A customizable version of `extends` for checking whether one type is assignable to another. Refer {@link ExtendsStrictOptions} for the different ways you can customize the behavior of this type. @example ``` import type {ExtendsStrict} from 'type-fest'; type T1 = ExtendsStrict; //=> false type T2 = ExtendsStrict; //=> false type T3 = ExtendsStrict; //=> false ``` @see {@link ExtendsStrictOptions} @category Improved Built-in */ export type ExtendsStrict = _ExtendsStrict>; type _ExtendsStrict> = And, Options['strictAny']> extends true ? Or, IsUnknown> : IsNever extends true ? Options['strictNever'] extends true ? OrAll<[IsNever, IsAny, IsUnknown]> : true : Options['distributiveUnions'] extends true ? Left extends Right ? true : false : [Left] extends [Right] ? true : false; export {};