Type Manipulation Flashcards
What does the keyof
type operator do?
In TypeScript, the keyof
type operator is used to create a new type based on the keys (property names) of an existing type. It is often used in the context of creating more generic or reusable types, providing a way to extract the keys of an object and use them as a union type.
Here’s a simple example:
interface Person { name: string; age: number; } type PersonKeys = keyof Person; // "name" | "age"
“Documentation - Keyof Type Operator” (typescriptlang.org). Retrieved April 4, 2023.
What does the typeof
type operator do?
In TypeScript, the typeof
type operator is used to obtain the type of a value, variable, or expression. When used within a type context, it allows you to create new types based on the inferred type of an existing value or expression. This can be useful in cases where you want to create a type that matches the structure of an object, without having to explicitly define the object’s structure as a separate interface or type alias.
Here’s an example of how to use the typeof
type operator in TypeScript:
const exampleObject = { id: 1, name: "John Doe", email: "john.doe@example.com" }; type ExampleObjectType = typeof exampleObject; function logDetails(obj: ExampleObjectType) { console.log(`ID: ${obj.id}, Name: ${obj.name}, Email: ${obj.email}`); } logDetails(exampleObject); // This will work logDetails({ id: 2, name: "Jane Doe", email: "jane.doe@example.com" }); // This will also work logDetails({ id: 3, name: "Invalid", missingEmail: "missing@example.com" }); // This will cause a TypeScript error
“Documentation - Typeof Type Operator” (typescriptlang.org). Retrieved April 4, 2023.
Given this function
function f() { return { x: 10, y: 3 }; }
Create a type P
that represents the return type fo the f
function.
type P = ReturnType<typeof f>;
“Documentation - Typeof Type Operator” (typescriptlang.org). Retrieved April 4, 2023.
What are the limitations of the typeof
type operator?
TypeScript intentionally limits the sorts of expressions you can use typeof
on.
Specifically, it’s only legal to use typeof
on identifiers (i.e. variable names) or their properties. This helps avoid the confusing trap of writing code you think is executing, but isn’t:
// Meant to use = ReturnType<typeof msgbox> let shouldContinue: typeof msgbox("Are you sure you want to continue?"); // Error: ',' expected.
“Documentation - Typeof Type Operator” (typescriptlang.org). Retrieved April 4, 2023.
What do indexed access types do?
In TypeScript, indexed access types, also known as lookup types, allow you to access the type of a property of another type using a key.
This can be useful when you want to create a new type that’s based on a specific property of another type, or when you want to access a nested property’s type. Indexed access types use the syntax T[K]
, where T
is the type you want to access and K
is the key (property name) whose type you want to obtain.
Here’s an example of how to use indexed access types:
interface Person { id: number; name: string; email: string; } type PersonName = Person["name"]; // PersonName is of type string type PersonEmail = Person["email"]; // PersonEmail is of type string
“Documentation - Indexed Access Types” (typescriptlang.org). Retrieved April 4, 2023.
Can you use indexed access types with generics?
Yes, you can.
For example:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const person: Person = { id: 1, name: "John Doe", email: "john.doe@example.com" }; const personName = getProperty(person, "name"); // personName is inferred as string const personEmail = getProperty(person, "email"); // personEmail is inferred as string
In this example, we define a generic getProperty
function that takes an object of type T
and a key of type K
, where K
is a key of T
. The function returns a value of type T[K]
. This allows us to use the getProperty
function to access properties of various types and get the correct return type based on the input type and key.
“Documentation - Indexed Access Types” (typescriptlang.org). Retrieved April 4, 2023.
What does the satisfies
operator do?
The satisfies
operator checks if a given type satisfies a specific condition or interface.
For example Let’s create a type called personInfo
, which is a union of personName
and otherDetails
.
type personName = "John" | "Jack" | "Justin"; type otherDetails = { id: number; age: number; }; type personInfo = personName | otherDetails;
Now let’s create the Person
type.
type Person = { myInfo: personInfo; myOtherInfo: personInfo; };
The Person type has two properties, myInfo and myOtherInfo, both of which will be of type personInfo. This indicates that both properties can either be personName or otherDetails. Now, let’s create the variable applicant.
const applicant: Person = { myInfo: "John", myOtherInfo: { id: 123, age: 22 }, };
Now, let’s imagine we want to access myInfo and convert it to uppercase.
applicant.myInfo.toUpperCase(); // Error: Property 'toUpperCase' does not exist on type 'personInfo' and Property 'toUpperCase' does not exist on type 'otherDetails'
This error occurs because TypeScript is unsure whether the value of myInfo
or myOtherInfo
is a string
or an object
since we have defined our personInfo
as a union of string
and object
.
In order to remove this error, we have to manually validate the property as shown below:
if (typeof applicant.myInfo === "string") { applicant.myInfo.toUpperCase(); }
Now, with the help of the satisfies
operator, you don’t need to do all this.
const applicant = { myInfo: "John", myOtherInfo: { id: 123, age: 22 }, } satisfies Person; applicant.myInfo.toUpperCase(); // no error
The satisfies
operator determines that the myInfo
variable is a string
and not an object
. This is because, before executing the code, it checks all the values of the Person
type. This operator ensures that we assign any value that satisfies the Person
type to the applicant variable.
“How to Use the TypeScript satisfies Operator” (freeCodeCamp.org). Retrieved November 14, 2023.