Everyday TypeScript: Type Intersections
Welcome to the Type Intersections lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
This course covers TypeScript types that you'll use in everyday application programming. It assumes that you already understand the basics of TypeScript, including basic generics, literal types, and type narrowing. If you're brand new to TypeScript, or to static types in general, then you may want to start with our TypeScript Basics course instead.
TypeScript allows us to define types that must match two other types simultaneously. For example, we might have a type
HasEmailthat requires an email field, and a typeCanBeAdminthat requires an admin flag. We can combine them into aUsertype that has both an email and an admin flag.The syntax
T1 & T2means "an object with all of the properties from bothT1andT2."(One of the code examples below causes a type error. When that happens anywhere in this course, you can answer with "type error".)
>
type HasEmail = {email: string};type CanBeAdmin = {admin: boolean};type User = HasEmail & CanBeAdmin;- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
let amir: User = {email: 'amir@example.com',admin: true,};amir.email;Result:
'amir@example.com'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
let amir: User = {email: 'amir@example.com',};amir.email;Result:
type error: Type '{ email: string; }' is not assignable to type 'User'. Property 'admin' is missing in type '{ email: string; }' but required in type 'CanBeAdmin'. Types defined as
Type1 & Type2are called intersection types.We can always narrow an intersection back to one of its parts. For example, we can narrow a
Userback to aHasEmail. However, from that point forward we only have aHasEmail. Any fields that came from other parts of theUserwon't be accessible.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
let amir: User = {email: 'amir@example.com',admin: true,}; - Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
function extractEmail({email}: HasEmail): string {return email;}extractEmail(amir);Result:
'amir@example.com'
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
function extractAdmin(hasEmail: HasEmail): boolean {return hasEmail.admin;}extractAdmin(amir);Result:
type error: Property 'admin' does not exist on type 'HasEmail'.