npm
npm i ts-roids
pnpm
pnpm i ts-roids
If you're only using types, you can install it as a devDependency
.
And if you're using decorators, set this.
{
"compilerOptions": {
// ...
"experimentalDecorators": true
}
}
Requires TypesScript v5.0
+
Checkout the full API reference for all usage examples with details.
PartializedUnion<T>
- Creates a union type where each variant has its specific properties required, while other properties are optional.UniqueArray<T>
- Create unique array type from a given array type T
, a set perse.Prune<T,N = NotIncluded>
- Prune a type T
by recursively omitting properties of type N
(defaults to NotIncluded
).UnionToTuple<T>
- Converts a union type T
into a tuple type, allowing for ordered access to the union's members.DeepToPrimitive<Obj>
- Recursively transforms an object type T into a type where all properties are replaced with their corresponding primitive types.Assign<Obj,ObjArr>
- Copies all enumerable own properties from one target object to a source array of objects.CapitalizeFirst<T>
- Capitalizes the first character of a string literal type while preserving the rest.Flip<Obj>
- Flips keys with values of an object type Obj
.DeepImmutable<Obj>
- Recursively turns the proprties within a given object type T
immutable, as in have all the properties with the readonly
modifier.Deepmutable<Obj>
- Recursively mutates all the proprties within a given object type T
, as in have all the properties without the readonly
modifier.DeepRequired<Obj>
- Recursively make all object properties required.DeepNotRequired<Obj>
- Recursively make all object properties not required.DeepOmit<Obj,P>
- Recursively omits specified nested properties from an object, based on a given predicate P
.DeepPick<Obj,P>
- Deeply pick properties from a nested object, based on a given predicate P
.EmptyObject
- Represents any non-nullish value, basically {}
.EqualStrlen<S1, S2>
- Check if two strings S1
and S2
have the same length.PartialExcept<T, P>
- Makes all properties in T
optional except those in K
which remain required.FilterBy<Obj, P>
- Filters keys from the object type Obj
based on a specified predicate P
.Float<N>
- Type representing a float.If<C, Do, Else>
- If C
evaluates true
, Do
, otherwise return Else
.IfEquals<T, P, Do, Else>
- Checks if type T
is equal to type P
. If T
is equal to P
, the type resolves to Do
, otherwise Else
.IfExtends<T, P, Do, Else>
- Checks if type T
extends type P
. if it does, the type resolves to Do
, otherwise Else
.ImmutableKeys<Obj>
- Retrieves the keys that are immutable (readonly
) from an object of type Obj
.Integer<N>
- Represents an integer.Abs<N>
- Get the absolute value of a Numeric
.And<B1,B2>
- Logical AND between two boolean types.EitherOneOrMany<T>
- Represents a type that can be either a single value of type T
or an array of values of type T
.Nullable
- Represents any non-nullish value, basically {}
.Equals<X,Y>
- Checks if two types X
and Y
are exactly equal.EvenNumeric<T>
- Represents an even Numeric
.ExcludeNull<T>
- Excludes null
from a type T
.ExcludeNullable<T>
- Excludes Nullable
from a type T
.ExcludeUndefined<T>
- Excludes undefined
from a type T
.KeysOfUnion<T>
- Extracts the union of keys from a given union of object types, useful for accessing all possible keys in unions.Simplify<T>
- Flattens the structure of a type by resolving intersections and simplifying nested mapped types, enhancing readability.Extends<T,U>
- Evaluates whether one type T
is assignable to another type U
.Falsy
- Represents a type that is falsy JavaScript.FalsyProperties<T>
- Extracts falsy properties from an object type T
.IsArrayIncludesTypeof<Arr, T>
- Checks if an array type Arr
includes one or more of T
type.IsBigInt<T>
- Checks if T
is a bigint
.IsBoolean<T>
- Checks if T
is a boolean
.IsDeepImmutable<Obj>
- Checks if all the nested properties of a given object Obj
are immutable.IsDeepMutable<Obj>
- Checks if all the nested properties of a given object Obj
are mutable.IsDeepNotRequired<Obj>
- Checks if all the properties of a given object (nested) are not required, as in, all properties have the ?
modifier.IsDeepRequired<Obj>
- Checks if all the properties of a given object (nested) are required, as in, all properties do not have the ?
modifier.IsExactlyAny<T>
- Checks if a type T
is exactly any
.IsExactlyBigInt<T>
- Checks if a type T
is exactly bigint
not a subtype of it.IsExactlyNumber<T>
- Checks if a type T
is exactly number
not a subtype of it.IsExactlyString<T>
- Checks if a type T
is exactly string
not a subtype of it.IsExactlySymbol<T>
- Checks if a type T
is exactly symbol
not a subtype of it.IsExactlyUnknown<T>
- Checks if a type T
is exactly unknown
not a subtype of it.IsFalsy<T>
- Checks if a given type T
is Falsy
.IsFloat<N>
- Checks if a given type T
is a Float<N>
.IsFunction<T>
- Checks if a given type T
is a function.IsInteger<N>
- Checks if a given Numeric
is an Integer<N>
.IsNever<T>:
- Checks if a type T
does not resolve, so never
.IsNewable<T>
- Checks if a type T
is Newable
.IsNullable<T>
- Checks if a type T
is Nullable
.IsNumber<T>
- Checks if a type T
is a number
.IsNumeric<T>
- Checks if a type T
is Numeric
.IsObject<T>
- Checks if a given type T
qualifies as an object.IsString<T>
- Check if a given type T
is a string
.IsSymbol<T>
- Check if a given type T
is a symbol
.IsTruthy<T>
- Check if a given type T
resolves to a truthy value.Keys<T>
- Retrieves the union type of keys (property names) of a type T
.Maybe<T>
- Type that might be Nullable
MaybeUndefined<T>
- Type that might undefined
.MutableKeys<Obj>
- Retrieves the keys that are mutable from an object of type Obj
.Nand<B1, B2>
- Logical NAND
between two boolean types B1
and B2
.NegativeFloat<N>
- Represents a negative (]-∞, 0[) Float<N>
.NegativeFloatString<S>
- Represents a negative Float<N>
parsed from a string
.NegativeInteger<N>
- Represents a negative (]-∞, 0[) Integer<N>
.NegativeIntegerString<S>
- Represents a negative Integer<N>
parsed from a string
.NewType<New, Base>
- Represents a new unique type derived from an existing base type. (branded type)Newable
- Represents constructor functions that can be invoked using the new keyword.NonRequiredKeys<Obj>
- Returns all non required keys of an object Obj
, as in any property of an object that is marked with ?
operator.Not<B>
- Negates a boolean type B
.Nullable
- Represents a type that can either be null
or undefined
.Numeric
- Represents a type that can either be number
or bigint
.NumerifyString<S>
- Turn a given string literal to a Numeric
, if possible.Methods<Obj>
- Get the literal names of keys that are methods in an object type Obj
.Properties<Obj>
- Get the literal names of keys that are properties in an object type Obj
.OddNumeric<T>
- Represents an odd Numeric
.OmitByType<Obj, T>
- Get a set of properties from Obj
whose type are not assignable to T
.OmitCommonKeys<Obj1, Obj2>
- Omit any common key between the the two objects,.OmitExactlyByType<Obj, T>
- Omit properties from Obj
whose type exactly matches T
.Optional<T>
- Represents a type that may be null
, similar to Python's Optional
type and Rust's Option
enum.Or<B1, B2>
- Logical OR
between two boolean types B1
and B2
.PickByType<Obj, T>
- Pick from Obj
a set of properties that match the type T
.PickCommonKeys<Obj1, Obj2>
- Get the common keys between two objects.PickExactlyByType<Obj, T>
- Get a set of properties from Obj
whose type exactly matches T
.PositiveFloat<N>
- Represents a positive ([0, +∞[) Float<N>
.PositiveFloatString<S>
- Represents a positive Float<N>
parsed from a string
.PositiveInteger<N>
- Represents a positive ([0, +∞[) Integer<N>
.PositiveIntegerString<S>
- Represents a negative Integer<N>
parsed from a string
.Primitive
- All primitive types.ReplaceKeys<Obj1,P,Obj2>
- Constructs a new type by replacing properties P
of type Obj
with object type Obj2
.RequiredKeys<Obj>
- Get the required keys of an object (shallow).SizedTuple<T,N>
- Creates a tuple with a specific length, where each element is of a given type.StringEndsWith<S,E>
- Checks if a string S
ends with E
StringStartsWith<S,St>
- Checks if a string S
starts with St
StringifyPrimitive<P>
- Turns a given Primitive
value (except symbol
) into its string representation.Strlen<S>
- Get the length of a string S
.TestType<T1, T2, Expected>
- Tests if type T1
and T2
are the same.TruthyProperties<T>
- Extracts truthy properties from an object type T
.UnionToIntersection<U>
- As the name implies, it turns a union into an intersection.Vals<Obj>
- Get the set of type values in a given object.Xor<B1, B2>
- Exclusive OR
between two boolean types B1
and B2
.The best way to understand how these types work is to check the tests directory. Each type has corresponding edge test cases that demonstrate its usage and expected behavior.
@Final
- Marks an object final, as in one cannot inherit from it.@Sealed
- Seals an object.@Frozen
- Freezes an object.@Singleton
- Ensures that only a single instance of the class can be created.Finalize and freeze objects
import type { Optional, NewType, MaybeUndefined } from 'ts-roids';
import { Final, Frozen, Singleton } from 'ts-roids';
type Bar = NewType<'Bar', string>;
type Baz = NewType<'Baz', string>;
type Secret = NewType<'Secret', string>;
abstract class BaseFoo<T> {
public abstract requestFoo(secret: Secret, baz: Baz): Promise<Optional<T>>;
}
@Final
@Frozen
@Singleton
class Foo<T> extends BaseFoo<T> {
private static readonly rnd = Math.random();
private readonly foo: T;
public bar: Optional<Bar>; // `Bar` then becomes readonly with the decorator
public constructor(foo: T, bar?: MaybeUndefined<Bar>) {
super();
this.foo = foo;
this.bar = bar ?? null;
}
public override async requestFoo(
secret: Secret,
baz: Baz
): Promise<Optional<T>> {
if (
Foo.rnd > 0.5 &&
secret.concat().toLowerCase() === '123' &&
baz.concat().toLowerCase() === 'baz' &&
this.bar !== null
) {
return await Promise.resolve(this.foo);
}
return null;
}
}
class SubFoo extends Foo<string> {
constructor(foo: string) {
super(foo);
}
}
// No problem with instantiation
const foo = new Foo('foo');
// The Singleton ensures the same instance is returned
const foo2 = new Foo('bar');
console.log(foo2 === foo); // True
// Since the object is final:
// The line below will cause a TypeError: Cannot inherit from the final class Foo
new SubFoo('subFoo');
// Since the object is frozen:
// The line below will cause a TypeError: Cannot add property 'requestFoo', object is not extensible
foo.requestFoo = async () => {
return await Promise.resolve('not foo');
};
// The line below will cause a TypeError: Cannot assign to read only property 'bar'
foo.bar = 'not bar' as Bar;
The TypeScript team has not yet introduced a built-in final modifier yet, check
this, this and many other requests.
Although they introduced override
in v4.3
.
Decorators like @Final
provide a limited way to emulate final behavior, these are merely band-aids for now, until TS officially supports a true final modifier.
You can also seal an object btw.
@Sealed
class Person {
constructor(name: string, age?: number) {}
}
const john = new Person('John', 30);
// Existing properties can still be modified
john.age = 31; // No Errors
// Existing properties cannot be re-configured nor deleted
(john as any).email = 'john@doe.com'; // TypeError: Cannot add property email,
// object is not extensible
delete john.age; // TypeError: Cannot delete property 'age'
See releases.