If you want to retrieve both the order and the specific literal types of the name
properties from the columns
array, annotating the type as an unordered SomeType[]
will make you lose track of the order. Changing it to a tuple may help, but then you'll need to specify the string literal types for the name
properties in each tuple element, creating a complex and redundant type.
Instead of annotating the type, you can infer it from the initializing value using a const
assertion to retain the order and literal types:
const columns = [
{ name: "first", someProp: true },
{ name: "second", someProp: true },
{ name: "one more", someProp: true }
] as const;
/* const columns: readonly [{
readonly name: "first";
readonly someProp: true;
}, {
readonly name: "second";
readonly someProp: true;
}, {
readonly name: "one more";
readonly someProp: true;
}] */
IntelliSense will show that columns
now has all the necessary information.
To extract only the name
property types, a utility type called NameMap<T>
can be created. It takes in a generic arraylike type T
with elements having a string
-valued name
property, and returns an arraylike type of just those name
property types:
type NameMap<T extends readonly { name: string }[]> =
{ [I in keyof T]: T[I]['name'] }
This is a mapped type that produces an array/tuple type. It extracts the type of the name
property for each element in the input type T
.
Testing it:
type TypeThatILookingFor = NameMap<typeof columns>;
// type TypeThatILookingFor = readonly ["first", "second", "one more"]
The output is as expected, providing the necessary type information.
By defining a function someFunc
that accepts the extracted TypeThatILookingFor
, you can ensure proper type checking when passing in values:
someFunc(["first", "second", "one more"]); // okay;
someFunc(["first", "next", "one more"]); // error!
someFunc(["first", "second"]); // error!
The types are enforced correctly, ensuring the integrity of the data being passed.