Is there a way to declare a type in typescript that 'extracts' the inner type of an array?
Example:
Let's say I already have something like this in my codebase:
export interface Cache {
events: Event[],
users: User[]
}
type CacheType = Event[] | User[];
//or maybe:
// type TypeOfProperty = T[keyof T];
// type CacheType = TypeOfProperty<Cache>;
What I want is something which would be equivalent to this:
type InnerCacheType = Event | User;
But without manually retyping it every time I add something to Cache
or CacheType
Is this possible in Typescript?
Array types may be identified by invoking Class. isArray() . To obtain a Class use one of the methods described in Retrieving Class Objects section of this trail.
An array is a special type of data type which can store multiple values of different data types sequentially using a special syntax. TypeScript supports arrays, similar to JavaScript.
Summary. In TypeScript, an array is an ordered list of values. An array can store a mixed type of values. To declare an array of a specific type, you use the let arr: type[] syntax.
Inline Type for Array of Objects in TypeScript The array of objects is defined inside the curly brackets {} . The array of objects can be defined using inline type.
This is possible with Typescript 2.8+. You can declare an Unpacked<T>
type as follows:
type Unpacked<T> = T extends (infer U)[] ? U : T;
Now you can do
type InnerCacheType = Unpacked<CacheType>; // Event | User
This is a condensed definition of the Unpacked
type given in the documentation.
This could also be achieved with a type query. ie.
type CacheType = Event[] | User[];
type InnerCacheType = CacheType[number]; // Event | User
TS Playground
If you look at this comment from the ts dev team
You're allowed to write
const t: Array<string>[number] = "hello";
as a roundabout way of writing
const t: string
So This will always hold true.
Let's assume that you can use TypeScript 2.1 or greater, otherwise there is no way to achieve what you're looking for.
Also, keep in mind that you're taking for granted that all the properties of the Cache
interface will be arrays. If this is not the case, your question becomes senseless, so I will also make this assumption.
Generally speaking, CacheType
can be written as
type CacheType = Cache[typeof Cache];
including any inherited properties. The obtained type is equivalent to Event[] | User[]
, however extracting the array components from such union type is unfeasible.
The solution is using mapped types. The InnerCacheType
you are looking for can be written as
type InnerCacheType = MappedCacheType[typeof MappedCacheType];
where
type MappedCacheType = { [P in keyof Cache]: Cache[P][0]; };
In fact, the last type is equivalent to
{ events: Event; users: User; }
Please notice that TypeScript keeps the names the same as the original ones.
Summarizing, without considering your use case, the way to express the component type of an array type T
is T[0]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With