1 | import { AnyRecord } from "../any-record";
|
2 | import { IsNever } from "../is-never";
|
3 | type IsUnion<TUnion> = UnionToTuple<TUnion>["length"] extends 1 ? false : true;
|
4 | type UnionToFunctionInsertion<TUnion> = (TUnion extends any ? (arg: () => TUnion) => any : never) extends (arg: infer TParam) => any ? TParam : never;
|
5 | type UnionToTuple<TUnion> = UnionToFunctionInsertion<TUnion> extends () => infer TReturnType ? [...UnionToTuple<Exclude<TUnion, TReturnType>>, TReturnType] : [];
|
6 | type ExactUnionLength<TValue, TShape, TValueLength = UnionToTuple<TValue>["length"], TShapeLength = UnionToTuple<TShape>["length"]> = TValueLength extends TShapeLength ? true : false;
|
7 | type Xor<T, U> = T extends true ? (U extends true ? true : false) : U extends false ? true : false;
|
8 | type And<TTuple> = TTuple extends [infer Head, ...infer Rest] ? Head extends true ? And<Rest> : false : TTuple extends [] ? true : false;
|
9 | type ObjectKeyExact<TValue, TShape> = And<[
|
10 | IsNever<Exclude<keyof TValue, keyof TShape>>,
|
11 | IsNever<Exclude<keyof TShape, keyof TValue>>
|
12 | ]>;
|
13 | type ObjectValueDiff<TValue, TShape> = {
|
14 | [TKey in keyof TValue]: Exclude<TValue[TKey], TShape[TKey & keyof TShape]>;
|
15 | }[keyof TValue];
|
16 | type ObjectValueExact<TValue, TShape> = And<[
|
17 | IsNever<ObjectValueDiff<TValue, TShape>>,
|
18 | IsNever<ObjectValueDiff<TShape, TValue>>
|
19 | ]>;
|
20 | type ObjectExact<TValue, TShape> = [TValue] extends [TShape] ? And<[
|
21 | Xor<IsUnion<TValue>, IsUnion<TShape>>,
|
22 | ExactUnionLength<TValue, TShape>,
|
23 | ObjectKeyExact<TValue, TShape>,
|
24 | ObjectValueExact<TValue, TShape>
|
25 | ]> extends true ? TValue : never : never;
|
26 | type IsArray<TValue> = [TValue] extends [readonly any[]] ? true : false;
|
27 | type IsReadonly<TArray> = Readonly<TArray> extends TArray ? true : false;
|
28 | type SameLength<TValue extends readonly any[], TShape extends readonly any[]> = IsNever<PrimitiveExact<TValue["length"], TShape["length"]>> extends true ? false : true;
|
29 | type ArrayExact<TValue extends readonly any[], TShape extends readonly any[]> = And<[
|
30 | IsArray<TValue>,
|
31 | IsArray<TShape>,
|
32 | SameLength<TValue, TShape>,
|
33 | Xor<IsReadonly<TValue>, IsReadonly<TShape>>
|
34 | ]> extends true ? [TValue, TShape] extends [readonly (infer TValueElement)[], readonly (infer TShapeElement)[]] ? Exact<TValueElement, TShapeElement> extends TValueElement ? TValue : never : never : never;
|
35 | type PrimitiveExact<TValue, TShape> = [TValue] extends [TShape] ? ([TShape] extends [TValue] ? TValue : never) : never;
|
36 | export type Exact<TValue, TShape> = [TValue] extends [readonly any[]] ? [TShape] extends [readonly any[]] ? ArrayExact<TValue, TShape> : never : [TValue] extends [AnyRecord] ? ObjectExact<TValue, TShape> : PrimitiveExact<TValue, TShape>;
|
37 | export {};
|