Type-ops -- type-level operators for TypeScript
npm install type-ops
type-opsexpect
ExpectT
IsFalseT
IsNeverT
IsNullableT
IsOptionalT
IsSameT
IsSubtypeOfT
IsTrueT
KeyofT
NotPropertiesOfSubtypeT
NotPropertiesOfTypeT
OptionalPropertiesT
PropertiesOfSubtypeT
PropertiesOfTypeT
RequiredPropertiesT
JsonT
OmitT
OverwriteT
PartialDeepT
ReadonlyDeepT
ReplaceT
RequiredDeepT
WithMutableT
WithPartialT
WithReadonlyT
WithRequiredT
WritableDeepT
MutableT
ConstructorT
DictT
FunctionT
NullableT
OptionalT
PrimitiveT
TaggedT
AndT
NotT
OrT
XorT
NoDistributeT
NoInferT
SelectT
~2.9.0, ^3.0.1.
commandline
npm i type-ops
`
Requirements
For some operators to work properly, strict mode must be enabled.
Dependencies
None.
License
MIT.
TODO
* [ ] Use dtslint.
Features
$3
These types can be used to test an arbitrary type for being conformant to a certain constraint.
#### expect
Induce a compilation error if TActual does not resolve to the type of expected.
##### Definition
`ts
declare const expect: () => { toBe(expected: TActual): void; };
`
##### Usage
`ts
interface I1 {
p1: string;
}
interface I2 {
p1: number;
}
// There will be a compilation error if IsSameTfalse':
expect>().toBe(false);
`
#### ExpectT
Induce a compilation error if TActual does not resolve to TExpected.
##### Definition
`ts
type ExpectT = never;
`
##### Usage
`ts
interface I1 { p1: string; }
interface I2 { p1: number; }
// Compilation will fail if IsSameTfalse':
type E1 = ExpectT, false>;
`
#### IsFalseT
Check if T is false.
Does not distribute over unions.
##### Definition
`ts
type IsFalseT = IsSameT;
`
#### IsNeverT
Check if T is never.
Does not distribute over unions.
##### Definition
`ts
type IsNeverT = IsSameT;
`
#### IsNullableT
Check if T is nullable.
Does not distribute over unions.
##### Definition
`ts
type IsNullableT = IsSubtypeOfT;
`
#### IsOptionalT
Check if T is optional.
Does not distribute over unions.
##### Definition
`ts
type IsOptionalT = IsSubtypeOfT;
`
#### IsSameT
Check if T and U are of the same shape.
Does not distribute over unions.
##### Definition
`ts
type IsSameT = AndT, IsSubtypeOfT>;
`
#### IsSubtypeOfT
Check if T is a subtype of U.
Does not distribute over unions.
#####
`ts
type IsSubtypeOfT = NoDistributeT extends U
? true
: false;
`
#### IsTrueT
Check if T is true.
Does not distribute over unions.
##### Definition
`ts
type IsTrueT = NotT>;
`
$3
These types can be thought of as "filters" on property keys of a particular type.
#### KeyofT
Extract all properties of T.
Distributes over unions.
##### Definition
`ts
type KeyofT = T extends any
? keyof T
: never;
`
#### NotPropertiesOfSubtypeT
Extract all properties of T which are not a subtype of U.
##### Definition
`ts
type NotPropertiesOfSubtypeT = Exclude>;
`
#### NotPropertiesOfTypeT
Extract all properties of T which are not of the same shape as U.
##### Definition
`ts
type NotPropertiesOfTypeT = Exclude>;
`
#### OptionalPropertiesT
Extract all optional properties of T.
##### Definition
`ts
type OptionalPropertiesT = {
[K in keyof T]-?: IsOptionalT extends false
? never
: K;
}[keyof T];
`
#### PropertiesOfSubtypeT
Extract all properties of T which are a subtype of U.
##### Definition
`ts
type PropertiesOfSubtypeT = {
[K in keyof T]: IsSubtypeOfT extends false
? never
: K;
}[keyof T];
`
#### PropertiesOfTypeT
Extract all properties of T which are of the same shape as U.
##### Definition
`ts
type PropertiesOfTypeT = {
[K in keyof T]: IsSameT extends false
? never
: K;
}[keyof T];
`
#### RequiredPropertiesT
Extract all required properties of T.
##### Definition
`ts
type RequiredPropertiesT = {
[K in keyof T]-?: IsOptionalT extends false
? K
: never;
}[keyof T];
`
$3
These are just mapped conditional types.
#### JsonT
Represent T after JSON serialization round-trip.
Distributes over unions.
##### Definition
`ts
interface _JsonArrayT extends Array> { }
type _CleanT = OmitT>;
type _JsonObjectT = {
[K in keyof T]: JsonT;
};
type JsonT = T extends string | number | boolean | null
? T
: T extends Function | symbol | undefined
? never
: T extends Array | ReadonlyArray
? _JsonArrayT
: T extends Map | ReadonlyMap | WeakMap | Set | ReadonlySet | WeakSet
? { }
: T extends { toJSON(key?: any): infer U; }
? U
: _CleanT<_JsonObjectT>;
`
#### OmitT
Omit properties K from T.
##### Definition
`ts
type OmitT = Pick>;
`
#### OverwriteT
Overwrite properties K of T with matching properties of U and add properties which are unique to U.
##### Definition
`ts
type OverwriteT = OmitT & U;
`
##### Usage
`ts
interface I1 {
p1: string;
p2: string;
p3: string;
}
interface I2 {
p2: number;
p3: number;
p4: number;
}
type I3 = OverrideT;
const i3: I3 = {
p1: 'v1',
p2: 2,
p3: 3,
p4: 4,
};
`
#### PartialDeepT
Recursively make all properties of T optional.
##### Definition
`ts
interface _PartialDeepArray extends Array> { }
interface _PartialDeepReadonlyArray extends ReadonlyArray> { }
type _PartialDeepObjectT = {
[K in keyof T]: PartialDeepT;
};
export type PartialDeepT = T extends Array
? _PartialDeepArray
: T extends ReadonlyArray
? _PartialDeepReadonlyArray
: T extends Function | PrimitiveT
? T
: Partial<_PartialDeepObjectT>;
`
#### ReadonlyDeepT
Recursively make all properties of T readonly.
##### Definition
`ts
interface _ReadonlyDeepArray extends Array> { }
interface _ReadonlyDeepReadonlyArray extends ReadonlyArray> { }
type _ReadonlyDeepObjectT = {
[K in keyof T]: ReadonlyDeepT;
};
export type ReadonlyDeepT = T extends Array
? _ReadonlyDeepArray
: T extends ReadonlyArray
? _ReadonlyDeepReadonlyArray
: T extends Function | PrimitiveT
? T
: Readonly<_ReadonlyDeepObjectT>;
`
#### ReplaceT
Replace properties K of T with matching properties of U.
##### Definition
`ts
type ReplaceT = OmitT & Pick;
`
##### Usage
`ts
interface I1 {
p1: string;
p2: string;
p3: string;
p4: string;
}
interface I2 {
p2: number;
p3: number;
p4: number;
p5: number;
}
type I3 = ReplaceT;
const i3: I3 = {
p1: 'v1',
p2: 2,
p3: 'v3',
p4: 4,
};
`
#### RequiredDeepT
Recursively make all properties of T required.
##### Definition
`ts
interface _RequiredDeepArray extends Array> { }
interface _RequiredDeepReadonlyArray extends ReadonlyArray> { }
type _RequiredDeepObjectT = {
[K in keyof T]: RequiredDeepT;
};
export type RequiredDeepT = T extends Array
? _RequiredDeepArray
: T extends ReadonlyArray
? _RequiredDeepReadonlyArray
: T extends Function | PrimitiveT
? T
: _RequiredDeepObjectT>;
`
#### WithMutableT
Make properties K of T mutable.
##### Definition
`ts
type WithMutableT = ReplaceT, K>;
`
#### WithPartialT
Make properties K of T optional.
##### Definition
`ts
type WithPartialT = ReplaceT, K>;
`
#### WithReadonlyT
Make properties K of T readonly.
##### Definition
`ts
type WithReadonlyT = ReplaceT, K>;
`
#### WithRequiredT
Make properties K of T required.
##### Definition
`ts
type WithRequiredT = ReplaceT, K>;
`
#### WritableDeepT
Recursively make all properties of T mutable.
##### Definition
`ts
interface _MutableDeepArray extends Array> { }
interface _MutableDeepReadonlyArray extends ReadonlyArray> { }
type _MutableDeepObjectT = {
[K in keyof T]: MutableDeepT;
};
type MutableDeepT = T extends Array
? _MutableDeepArray
: T extends ReadonlyArray
? _MutableDeepReadonlyArray
: T extends Function | PrimitiveT
? T
: _MutableDeepObjectT>;
`
#### MutableT
Make all properties of T mutable.
##### Definition
`ts
type MutableT = {
-readonly [K in keyof T]: T[K];
};
`
$3
#### ConstructorT
A constructor of TInstances from TArguments.
##### Definition
`ts
type ConstructorT = new(...args: TArguments) => TInstance;
`
#### DictT
A dictionary of TValues.
##### Definition
`ts
interface DictT {
[propertyKey: string]: TValue;
}
`
#### FunctionT
A function mapping TArguments to TResult.
##### Definition
`ts
type FunctionT = (...args: TArguments) => TResult;
`
#### NullableT
Make T nullable.
##### Definition
`ts
type NullableT = OptionalT | null;
`
#### OptionalT
Make T optional.
##### Definition
`ts
type OptionalT = T | undefined;
`
#### PrimitiveT
A primitive.
##### Definition
`ts
type PrimitiveT = string | symbol | number | boolean | undefined | null;
`
#### TaggedT
Make tagged type from T using tag TTag.
It can be used to create an opaque alias of T.
##### Definition
`ts
declare const _RAW_TYPE: unique symbol;
declare const _TAG_TYPE: unique symbol;
type TaggedT = T & {
[_RAW_TYPE]: T;
[_TAG_TYPE]: TTag;
};
`
##### Usage
`ts
// I1' is an opaque type alias of string' tagged w/ A':
string' to its opaque typedef:
let i1: I1 = 'v1' as I1;
i1 = 'v2' as I1;
// i1 = 'v3'; // Compilation will fail.
// Underlying raw type (string') can be retrieved through lookup type:
I2' has the same shape as I1':
I3' is an opaque type alias of string' tagged w/ B'.
type I3 = UniqueT;
let i3: I3 = 'v5' as I3;
// I1' and I3' are incompatible:
// i1 = i3;
// i1 = i3 as I1; // Type assertion will not make any difference.
// i3 = i1;
// i3 = i1 as I3; // Ditto.
const i31: RawT = i1;
// I4' has the same shape as I1':
type I4 = RetaggedT;
let i4: I4 = i3 as RawT as I4;
i4 = i1;
i1 = i4;
`
##### RawT
Extract raw type of tagged T.
Distributes over unions.
###### Definition
`ts
type RawT = T extends UniqueT
? U
: T;
`
##### TagT
Extract tag from tagged T.
Distributes over unions.
###### Definition
`ts
type TagT = T extends UniqueT
? TTag
: never;
`
##### RetaggedT
Retag a tagged T using tag TTag.
Distributes over unions.
###### Definition
`ts
type RetaggedT = T extends TaggedT
? TaggedT
: TaggedT;
`
$3
#### AndT
Logical "and" of T and U.
Distributes over unions.
###### Definition
`ts
type AndT = T extends false
? false
: U extends false
? false
: true;
`
#### NotT
Logical "not" of T.
Distributes over unions.
###### Definition
`ts
type NotT = T extends false
? true
: false;
`
#### OrT
Logical "or" of T and U.
Distributes over unions.
###### Definition
`ts
type OrT = T extends false
? U extends false
? false
: true
: true;
`
#### XorT
Logical "xor" of T and U.
Distributes over unions.
###### Definition
`ts
type XorT = T extends false
? U extends false
? false
: true
: U extends false
? true
: false;
`
$3
#### NoDistributeT
Prevent distribution over T.
##### Definition
`ts
type NoDistributeT = T extends any
? T
: never;
`
#### NoInferT
Prevent type inference on T.
##### Definition
`ts
type NoInferT = T & Pick;
`
##### Usage
`ts
declare const f1: (i1: T, i2: T) => void;
f1({ p1: 'v1', p2: 'v2' }, { p1: 'v1' }); // An error sneaks in.
declare const f2: (i1: T, i2: NoInferT) => void;
// f2({ p1: 'v1', p2: 'v2' }, { p1: 'v1' }); // Causes compilation error.
f2({ p1: 'v1', p2: 'v2' }, { p1: 'v1', p2: 'v2' });
`
#### SelectT
Extract a member of a tagged union T using TTagKey as a tag property and TValue as its type.
##### Definition
`ts
type SelectT = Extract>;
`
##### Usage
`ts
declare const TAG: unique symbol;
interface I1 {
[TAG]: 'I1';
p1: string;
}
interface I2 {
[TAG]: 'I2';
p1: number;
}
type I3 = I1 | I2;
type A11 = TaggedUnionMemberT; // Resolves to I1'.