import { AnyRecord } from "../any-record"; import { IsNever } from "../is-never"; type IsUnion = UnionToTuple["length"] extends 1 ? false : true; type UnionToFunctionInsertion = (TUnion extends any ? (arg: () => TUnion) => any : never) extends (arg: infer TParam) => any ? TParam : never; type UnionToTuple = UnionToFunctionInsertion extends () => infer TReturnType ? [...UnionToTuple>, TReturnType] : []; type ExactUnionLength["length"], TShapeLength = UnionToTuple["length"]> = TValueLength extends TShapeLength ? true : false; type Xor = T extends true ? (U extends true ? true : false) : U extends false ? true : false; type And = TTuple extends [infer Head, ...infer Rest] ? Head extends true ? And : false : TTuple extends [] ? true : false; type ObjectKeyExact = And<[ IsNever>, IsNever> ]>; type ObjectValueDiff = { [TKey in keyof TValue]: Exclude; }[keyof TValue]; type ObjectValueExact = And<[ IsNever>, IsNever> ]>; type ObjectExact = [TValue] extends [TShape] ? And<[ Xor, IsUnion>, ExactUnionLength, ObjectKeyExact, ObjectValueExact ]> extends true ? TValue : never : never; type IsArray = [TValue] extends [readonly any[]] ? true : false; type IsReadonly = Readonly extends TArray ? true : false; type SameLength = IsNever> extends true ? false : true; type ArrayExact = And<[ IsArray, IsArray, SameLength, Xor, IsReadonly> ]> extends true ? [TValue, TShape] extends [readonly (infer TValueElement)[], readonly (infer TShapeElement)[]] ? Exact extends TValueElement ? TValue : never : never : never; type PrimitiveExact = [TValue] extends [TShape] ? ([TShape] extends [TValue] ? TValue : never) : never; export type Exact = [TValue] extends [readonly any[]] ? [TShape] extends [readonly any[]] ? ArrayExact : never : [TValue] extends [AnyRecord] ? ObjectExact : PrimitiveExact; export {};