SimplyTyped
repository·master·Indexed 20 days ago
https://github.com/andnp/simplytypedA TypeScript utility library providing advanced type manipulation tools for objects, strings, tuples, numbers, and conditionals. Version 1.1.0 includes helpers such as DeepPartial, DeepReadonly, StrictUnion, and UnionToIntersection, as well as type-level math operations and runtime utilities like isKeyOf and objectKeys.
What's inside simplytyped
- SimplyTyped is a TypeScript utility library designed to provide the building blocks for creating concise and complex types. Unlike more experimental libraries, it aims to be driven by industry use cases, often providing a thin layer over built-in TypeScript functionality to facilitate advanced type manipulation.
Install SimplyTyped via npm
masterTo use SimplyTyped in a Node.js or standard TypeScript project, install it as a development dependency using npm.
npm install --save-dev simplytypedUse SimplyTyped with Deno
masterIf you are using the Deno runtime, you can use SimplyTyped by importing the Deno-specific edition directly from unpkg.
import { ... } from 'https://unpkg.com/simplytyped/edition-deno/index.ts';Use runtime utilities: isKeyOf, objectKeys, and taggedObject
masterRuntime functions for object manipulation and type guarding:
isKeyOf(obj, key): A type guard that markskeyas a valid key ofobjif it exists.objectKeys(obj): Returns an array of keys for the given object, with the return type correctly typed as an array of the object's keys (unlike nativeObject.keys).taggedObject(obj, key): Transforms an object by adding a tag (the value ofkey) to every sub-object within it. Useful for tagged unions/reducers.
const o = { a: 'hi', b: 22 }; const key: string = 'a'; if (isKeyOf(o, key)) { // key is now typed as 'a' | 'b' } const tagged = taggedObject({ a: { val: 1 } }, 'name'); // Result: { a: { name: 'a', val: 1 } }Define function types with AnyFunc and Predicate
masterUtilities for concise function type definitions:
AnyFunc: Represents a function that takes any arguments and returnsany. Can be specialized with a return type:AnyFunc<number>returnsnumber.ArgsAsTuple<F>: Extracts the arguments of a functionFas a tuple (up to 7 arguments).ConstructorFunction<T>: Represents the constructor for a typeT.OverwriteReturn<F, R>: Takes a functionFand modifies its return type toR.Predicate<T>: Defines a function that takes an argument of typeTand returns aboolean.
type F = (x: number, y: string) => any; type Args = ArgsAsTuple<F>; // [number, string] type P = Predicate<string>; // (arg: string) => booleanUse PromiseOr to handle sync and async types
masterThe
PromiseOr<T>utility returns the typeTor aPromisecontainingT. This is helpful when a function might return a value immediately or wrap it in a promise.type got = PromiseOr<string>; // Promise<string> | stringPerform math operations on numeric types
masterSimplyTyped allows performing basic arithmetic at the type level:
Add<A, B>: Adds two numbers.Sub<A, B>: Subtracts B from A.Next<T>: Returns T + 1.Prev<T>: Returns T - 1.IsOne<T>,IsZero<T>: Boolean checks for 1 and 0.NumberEqual<A, B>: ReturnsTrueif numbers are equivalent.NumberToString<T>: Converts a number type to its string literal equivalent.
type sum = Add<12, 38>; // 50 type diff = Sub<22, 12>; // 10 type str = NumberToString<22>; // '22'Use NoDistribute to prevent conditional type distribution
masterIn TypeScript, conditional types distribute over unions when the checked type is a naked type parameter.
NoDistribute<T>prevents this behavior by wrapping the type in a way that makes it no longer 'naked', ensuring the conditional is evaluated once against the entire union rather than once for each member.Note:
NoDistributemust be used within the definition of the conditional type itself to be effective. Passing aNoDistribute-wrapped type into a standard distributive conditional will still result in distribution.type IsString<T> = T extends string ? "Yes" : "No"; type IsStringNoDistribute<T> = NoDistribute<T> extends string ? "Yes" : "No"; // Evaluates as: ("foo" | 42) extends string ? "Yes" : "No" type T2 = IsStringNoDistribute<"foo" | 5>; // Result: "No"Manage nullability with Nullable and NonNullable
masterSimplyTyped provides utilities to explicitly manage
nullandundefinedin types:Nullable<T>: Marks a type asT | null | undefined.NonNullable<T>: Removesnullandundefinedfrom a type (Note: this may overlap with the built-in TypeScriptNonNullable).
type got = Nullable<string>; // string | null | undefined type notNull = NonNullable<Nullable<string>>; // stringUse conditional logic with And, Or, Not, If, etc.
masterImplement complex conditional logic using boolean type utilities:
If<Condition, TrueType, FalseType>: ReturnsTrueTypeifConditionisTrue, otherwiseFalseType.And<A, B>,Or<A, B>,Xor<A, B>,Nand<A, B>,Not<A>: Standard boolean logic gates.
type conditional<C extends Bool> = If<C, number, string>; type res = conditional<True>; // numberConvert unions to intersections with UnionToIntersection
masterThe
UnionToIntersection<T>utility converts a union type into an intersection type. This is particularly useful for transforming a union of objects into a single object containing all properties from the union members.type got = UnionToIntersection<{ a: 0 } | { b: 1 } | { c: 2 }>; // Result: { a: 0, b: 1, c: 2 }Use NoInfer to prevent type inference in generic functions
masterThe
NoInfer<T>utility prevents a specific type parameter from being used to infer the typeTin a generic function. This is useful when you have multiple arguments and want to ensure that the type of one argument does not influence the inferred type of the generic parameter, even if they are related in a union.function doStuff<T>(x: T, y: NoInfer<T | 'there'>): T { return x; } const hi = 'hi' as 'hi' | number; const there = 'there'; const x = doStuff(hi, there); // x is inferred as 'hi' | number, not influenced by 'there'