Learn TypeScript
Quiz
Quiz
Test your knowledge on type narrowing with this quiz.
Consider the code below:
type Person = { name: string; address?: { line1: string; line2: string; state: string; zipcode: string; }}function validatePersonAddress(person: Person) { if (person.address === undefined) { throw 'Invalid address' }}function logZipcode(person: Person) { validatePersonAddress(person); console.log(person.address.zipcode);}
A type error is raised on the console.log
statement because TypeScript thinks person.address
could be undefined
. How can we resolve this problem?
Make address
a required property in the Person
type.
Turn strict mode off.
Use the following type assertion n the console.log
statement:
Copy console.log((person.address as any).zipcode);
What is the type of level
in the console.log
statement below:
Copy type Level = "low" | "medium" | "high";function logLevel(level: Level) { if (level === "high") { console.warn(level); } }
string
'high'
Level
Consider the code below:
Copy function convert(amount: number | string) { if (/* TODO: check if type is number */) { return amount; } else { return Number(amount); }}
What type guard can we use to check amount
is a number?
amount instanceof number
typeof amount === 'number'
Consider the code below:
Copy class Dog { woff() { console.log("woff") }}class Cat { meow() { console.log("meow") }}function speak(animal: Dog | Cat) { if (/* TODO: check if type is Dog */) { animal.woff(); } else { animal.meow(); }}
What type guards can we use to check animal
is of type Dog
?
animal instanceof Dog
typeof animal === 'Dog'
'woff' in animal
Consider the code below:
Copy interface Product { name: string; price: number; getPrice: () => number;}interface DiscountedProduct { name: string; price: number; getPrice: () => number; getDiscountedPrice: () => number;}function getPrice(product: Product | DiscountedProduct) { if (isDiscountedProduct(product)) { return product.getDiscountedPrice(); } else { return product.getPrice(); }}
What could an implementation of the isDiscountedProduct
type guard function be?
Copy function isDiscountedProduct( product: Product | DiscountedProduct): product is DiscountedProduct { return product.price > 10;}
Copy function isDiscountedProduct( product: Product | DiscountedProduct): asserts product is DiscountedProduct { return product.price > 10;}
Copy function isDiscountedProduct( product: Product | DiscountedProduct): asserts product is DiscountedProduct { if (product.price <= 10) { throw new Error("Not a discounted product"); }}
Consider the code below:
Copy interface Product { name: string; price: number; getPrice: () => number;}interface DiscountedProduct { name: string; price: number; getPrice: () => number; getDiscountedPrice: () => number;}function getDiscountedPrice(product: Product | DiscountedProduct) { assertDiscountedProduct(product); return product.getDiscountedPrice();}
What could an implementation of the assertDiscountedProduct
type guard function be?
Copy function assertDiscountedProduct(product: Product | DiscountedProduct): product is DiscountedProduct { return product.price > 10;}
Copy function assertDiscountedProduct(product: Product | DiscountedProduct): asserts product is DiscountedProduct { if (product.price <= 10) { throw new Error("Not a discounted product"); };}
Consider the code below:
Copy type Button = | { kind: "round"; renderIcon: () => void } | { kind: "normal"; renderText: () => void };function render(button: Button) { if (button.kind === "round") { button.renderIcon(); } else { button.renderText(); }}
Will a type error occur on the above code?
Yes because renderIcon
and renderText
don't exist in the Button
type.
No type errors will occur.