yet another Typescript type library for advanced types
yet another Typescript type library for advanced types
Yet another typing library. This differs by aiming to be less experimental than others, driven by industry use cases.
Many of the exposed types are a very thin layer above built in functionality. The goal is to provide all of the building blocks necessary to make concise, yet complex types.
npm install --save-dev simplytypedTo use with Deno, import https://unpkg.com/simplytyped/edition-deno/index.ts
AllKeys - AllRequired - CombineObjects - DeepPartial - DeepReadonly - DiffKeys - ElementwiseIntersect - GetKey - HasKey - Intersect - KeysByType - Merge - ObjectKeys - ObjectType - Omit - Optional - Overwrite - PlainObject - PureKeys - Required - SharedKeys - StrictUnion - StringKeys - TaggedObject - TryKey - UnionizeProperties - UnionKeys
NoDistribute - NoInfer - Nominal - Nullable - PromiseOr - UnionToIntersection
AnyFunc - ArgsAsTuple - ConstructorFunction - OverwriteReturn - Predicate
DropString - StringEqual - UnionContains
IntersectTuple - Length - UnionizeTuple
Add - IsOne - IsZero - Next - NumberEqual - Numbers - NumberToString - Prev - Sub
And - If - Nand - Not - Or - Xor
IsAny - IsArray - IsBoolean - IsFunction - IsNever - IsNil - IsNull - IsNumber - IsObject - IsString - IsStringFunction - IsType - IsUndefined
isKeyOf - objectKeys - Readonly - taggedObject
Gets all keys between two objects.
test('Can get all keys between objects', t => {
type a = { w: number, x: string };
type b = { x: number, z: boolean };
type got = AllKeys;
type expected = 'w' | 'x' | 'z';
assert(t);
assert(t);
});Marks all keys as required.
test('Can make all fields of options object required (not optional and not nullable)', t => {
type x = { a?: string, b: number | undefined };
type got = AllRequired;
type expected = { a: string, b: number };
assert(t);
assert(t);
});Takes two objects and returns their intersection.
This combines all keys and uses ObjectType to "clean up" the resultant object.
Useful for making extremely complex types look nice in VSCode.
test('Can combine two objects (without pesky & in vscode)', t => {
type a = { x: number, y: 'hi' };
type b = { z: number };
type got = CombineObjects;
type expected = {
x: number,
y: 'hi',
z: number
};
assert(t);
assert(t);
});Uses Partial to make every parameter of an object optional (| undefined).
Iterates through arrays of objects and nested objects.
…Uses Readonly to make every parameter of an object - and its sub-objects recursively - readonly.
…Gets all of the keys that are different between two objects.
This is a set difference between keyof T and keyof U.
Note that calling this with arguments reversed will have different results.
test('Can get all keys that are different between objects', t => {
type a = { x: number, y: string };
type b = { y: string, z: number };
type gotA = DiffKeys;
type gotB = DiffKeys;
assert(t);
assert(t);
});Takes two objects and returns their element-wise intersection. Note: this removes any key-level information, such as optional or readonly keys.
…Gets the value of specified property on any object without compile time error (Property 'b' does not exist on type '{ a: string; }'.) and the like.
Returns never if the key is not on the object.
It helps to use `If {
type obj = { x: number, y: string };
type expected = number;
type got = GetKey;
assert(t);
assert(t);
});
test('Will get never if key does not exist', t => {
type obj = { x: number, y: string };
type expected = never;
type got = GetKey;
assert(t);
assert(t);
});
### HasKey
Returns `True` if a key, `K`, is present in a type, `T`, else `False`.
### Intersect
Returns only the shared properties between two objects.
All shared properties must be the same type.
```ts
test('Can get an object with only shared properties', t => {
type a = { x: number, y: string };
type b = { y: string, z: string };
type expected = { y: string };
type got = Intersect;
assert(t);
assert(t);
});Gets all keys that point to a given type.
test('Can filter object keys by right side type', t => {
type obj = {
a: 1,
b: 2,
c: 3,
};
type expected = 'a' | 'b';
type got = KeysByType;
assert(t);
assert(t);
});Much like _.merge in javascript, this returns an object with all keys present between both objects, but conflicts resolved by rightmost object.
test('Can merge two objects, resolving matching keys by rightmost object', t => {
type a = { x: number, y: string };
type b = { y: number, z: string };
type got = Merge;
type expected = { x: number, y: number, z: string };
assert(t);
assert(t);
});
test('Can merge an object containing all strings as keys', t => {
type a = {
y: string;
[s: string]: string;
};
type b = { x: number, y: number };
type got = Merge;
type expected = { x: number, y: number } & Record;
assert(t);
assert(t);
});Objects can be indexed by multiple types: string, number, symbol.
For safe compatibility with typescript version, this type will always
have the correct set of object key types for the current version of TS.
This is useful for functions that must take a key, instead of K extends string,
use K extends ObjectKeys.
Takes any type and makes it an object type.
Useful when combined with & intersection types.
test('Can turn an object into another object', t => {
type obj = { x: number, y: string };
type expected = obj;
type got = ObjectType;
assert(t);
assert(t);
});Gives back an object with listed keys removed.
This is the opposite of Pick.
test('Can omit keys from an object', t => {
type a = { x: number, y: string, z: boolean };
type got = Omit;
type expected = { z: boolean };
assert(t);
assert(t);
});Mark specific keys, K, of T as optional (think Partial).
test('Can make properties optional', t => {
type x = { x: number, y: string, z: 'hello there' };
type expected = { x?: number, y?: string, z: 'hello there' };
type got = Optional;
assert(t);
assert(t);
});Can change the types of properties on an object.
This is similar to Merge, except that it will not add previously non-existent properties to the object.
test('Can overwrite properties on an object', t => {
type a = { x: number, y: string, z: 'hello there' };
type expected = { x: number, y: string, z: 'hello' | 'there' };
type got1 = Overwrite;
type got2 = Overwrite;
assert(t);
assert(t);
assert(t);
assert(t);
});An object with string keys and values of type any.
When an object has optional or readonly keys, that information is contained within the key.
When using optional/readonly keys in another object, they will retain optional/readonly status.
PureKeys will remove the optional/readonly status modifiers from keys.
Mark specific keys, K, of T as required.
test('Can make certain fields of options object required', t => {
type x = { a?: string, b: number | undefined };
type got1 = Required;
type got2 = Required;
type got3 = Required;
type expected1 = { a: string, b: number | undefined };
type expected2 = { a?: string, b: number };
type expected3 = { a: string, b: number };
assert(t);
assert(t);
assert(t);
});Gets all of the keys that are shared between two objects.
test('Can get keys that are same between objects', t => {
type a = { x: number, y: string };
type b = { x: string, y: string, z: boolean };
type got = SharedKeys;
type expected = 'x' | 'y';
assert(t);
assert(t);
});Makes a union 'strict', such that members are disallowed from including the keys of other members
For example, {x: 1, y: 1} is a valid member of {x: number} | {y: number},
but it's not a valid member of StrictUnion.
test('disallow union members with mixed properties', t => {
type a = { a: number };
type b = { b: string };
type good1 = {a: 1};
type good2 = {b: "b"};
type bad = {a: 1, b: "foo"};
type isStrict = T extends Array ? 'Yes' : 'No';
type strictUnion = [good1, good2];
type nonStrictUnion = [good1, good2, bad];
assert, 'Yes'>(t);
assert, 'No'>(t);
});Typescript 2.9 introduced number | symbol as possible results from keyof any.
For backwards compatibility with objects containing only string keys, this will
exclude any number | symbol keys from keyof.
For discriminated unions of objects, it is important to have a single "tag" property. Creates an object with each entry being tagged by the key defining that entry.
Like GetKey, but returns unknown if the key is not present on the object.
Get a union of the properties of an object.
test('Can get a union of all values in an object', t => {
type a = { x: 'hi', y: 'there', z: 'friend' };
type got = UnionizeProperties;
type expected = 'hi' | 'there' | 'friend';
assert(t);
assert(t);
});test('Can get all keys between objects in a union', t => {
type a = { w: number, x: string };
type b = { x: number, z: boolean };
type c = { y: boolean, z: string };
type got = UnionKeys;
type expected = 'w' | 'x' | 'y' | 'z';
assert(t);
assert(t);
});Prevent T from being distributed in a conditional type.
A conditional is only distributed when the checked type is naked type param and T & {} is not a
naked type param, but has the same contract as T.
test("can create a conditional type that won't distribute over unions", t => {
type IsString = T extends string ? "Yes" : "No";
type IsStringNoDistribute = NoDistribute extends string ? "Yes" : "No";
/**
* Evaluates as:
* ("foo" extends string ? "Yes" : "No")
* | (42 extends string ? "Yes" : "No")
*/
type T1 = IsString;
assert(t);
assert(t);
/**
* Evaluates as:
* ("foo" | 42) extenNo open issues yet, or sync has not completed.