/** * In/Out parameter */ export type Invariant = (_: T) => T; /** * Out parameter */ export type Covariant = (_: never) => T; /** * In parameter */ export type Contravariant = (_: T) => void; /** * In/Out parameter */ export type InvariantParam = { type: 'invariant'; value: T; }; /** * Out parameter */ export type CovariantParam = { type: 'covariant'; value: T; }; /** * In parameter */ export type ContravariantParam = { type: 'contravariant'; value: T; }; export type UnknownParam = { type: unknown; value: unknown; }; export type Param = InvariantParam | CovariantParam | ContravariantParam | UnknownParam; export type VarianceParamOf = T[N]['type']; export type VarianceOf> = $variance extends 'invariant' ? Invariant : $variance extends 'covariant' ? Covariant : $variance extends 'contravariant' ? Contravariant : never; export type ZipWithVariance = A extends [infer AHead, ...infer ATail] ? B extends [infer BHead, ...infer BTail] ? ZipWithVariance extends 'contravariant' ? AHead & BHead : AHead | BHead ]> : ZipWithVariance : B extends [infer BHead, ...infer BTail] ? ZipWithVariance<[], BTail, Params, [...$acc, BHead]> : $acc;