npm i @kakasoo/deep-strict-types
DeepStrictTypes extends TypeScript utility types, enabling safe operations like Omit
and Pick
on deeply nested objects or arrays by specifying keys to be inferred. It provides strict and accurate type checks, simplifying tasks like removing a single key from a nested object without recombining multiple types. Quickly and precisely omit or pick the internal keys you need!
Extract all nested keys from an object T
, preserving its structure. Useful for safely handling specific keys at deeper levels of an object.
type Example = {
user: {
name: string;
address: {
city: string;
zip: number;
};
};
};
// Result: "user" | "user.name" | "user.address" | "user.address.city" | "user.address.zip"
type Keys = DeepStrictObjectKeys<Example>;
Also, We create function for this type! Application of existing Object.keys to nested objects.
type Target = { a: 1 }[][];
const keys = deepStrictObjectKeys({} as Target); // "[*].[*].a"[]
In arrays, elements are represented with the [*]
symbol, ensuring perfect inference even for nested structures.
Create a new type by excluding properties corresponding to key K
from object T
, preserving the nested structure.
type Example = {
user: {
name: string;
age: number;
};
};
// Result: { user: { age: number; } }
type Omitted = DeepStrictOmit<Example, 'user.name'>;
This is particularly effective for branded types. Below is an example using the typia
library:
test('Apply DeepStrictOmit to branding types', () => {
type TestInterface = {
id: string;
thumbnails: {
name: string & MinLength<1> & MaxLength<255>;
url: string;
}[];
};
type Question = DeepStrictOmit<TestInterface, 'id'>;
type IsAnswer = Equal<Question, { thumbnails: { name: string & MinLength<1> & MaxLength<255>; url: string }[] }>;
ok(typia.random<IsAnswer>());
});
Select properties corresponding to key K
from object T
, preserving the nested structure.
type Example = {
user: {
name: string;
age: number;
};
};
// Result: { user: { name: string; } }
type Picked = DeepStrictPick<Example, 'user.name'>;
Remove branding from type T
, even in deeply nested objects, simplifying the handling of branded types.
type BrandedType = { value: number & { unit: 'dollar' } };
// Result: { value: number; }
type Unbranded = DeepStrictUnbrand<BrandedType>;
Get the type of a specific key path from a nested object type T
. This is useful for extracting the type of deeply nested properties safely.
type Example = {
user: {
name: string;
address: {
city: string;
zip: number;
};
};
};
// Result: string
type CityType = GetType<Example, 'user.address.city'>;
// Result: { city: string; zip: number; }
type AddressType = GetType<Example, 'user.address'>;
interface Example {
a: number;
b: number;
c: {
d: string;
e: string;
f: {
g: boolean;
h: boolean;
}[];
}[];
}
declare const E: Example;
// Expected: { c: Array<{ d: string }> }
const answer = deepStrictAssert(E)('c[*].d');
This is just a part of the features provided by DeepStrictTypes, designed to enhance TypeScript's type manipulation capabilities and improve developer productivity. For more details, check out the library's full documentation.