The extends keyword in TypeScript is a Swiss Army knife of sorts. It's used in multiple contexts, including inheritance, generics, and conditional types. Understanding how to use extends effectively can lead to more robust, reusable, and type-safe code.
One of the primary uses of extends is in inheritance, allowing you to create new interfaces or classes that build upon existing ones.
interface User { firstName: string; lastName: string; email: string; } interface StaffUser extends User { roles: string[]; department: string; } const regularUser: User = { firstName: "John", lastName: "Doe", email: "[email protected]" }; const staffMember: StaffUser = { firstName: "Jane", lastName: "Smith", email: "[email protected]", roles: ["Manager", "Developer"], department: "Engineering" };
In this example, StaffUser extends User, inheriting all its properties and adding new ones. This allows us to create more specific types based on more general ones.
The extends keyword is also used for class inheritance:
class Animal { constructor(public name: string) {} makeSound(): void { console.log("Some generic animal sound"); } } class Dog extends Animal { constructor(name: string, public breed: string) { super(name); } makeSound(): void { console.log("Woof! Woof!"); } fetch(): void { console.log(`${this.name} is fetching the ball!`); } } const myDog = new Dog("Buddy", "Golden Retriever"); myDog.makeSound(); // Output: Woof! Woof! myDog.fetch(); // Output: Buddy is fetching the ball!
Here, Dog extends Animal, inheriting its properties and methods, and also adding its own.
The extends keyword is crucial when working with generics, allowing us to constrain the types that can be used with a generic function or class.
interface Printable { print(): void; } function printObject(obj: T) { obj.print(); } class Book implements Printable { print() { console.log("Printing a book."); } } class Magazine implements Printable { print() { console.log("Printing a magazine."); } } const myBook = new Book(); const myMagazine = new Magazine(); printObject(myBook); // Output: Printing a book. printObject(myMagazine); // Output: Printing a magazine. // printObject(42); // Error, number doesn't have a 'print' method
In summary, the extends keyword in the context of function printObject
T extends U ? X : Y
type ExtractNumber= T extends number ? T : never; type NumberOrNever = ExtractNumber ; // number type StringOrNever = ExtractNumber ; // never
Here, the ExtractNumber type takes a type parameter T. The conditional type checks whether T extends the number type. if does, the type resolves to T (which is number type). If it doesn't, the type resolves to never.
Now, let's consider the expression A | B | C extends A. This might seem counterintuitive at first, but in TypeScript, this condition is actually false. Here's why:
type Fruit = "apple" | "banana" | "cherry"; type CitrusFruit = "lemon" | "orange"; type IsCitrus= T extends CitrusFruit ? true : false; type Test1 = IsCitrus; // true type Test2 = IsCitrus; // false type Test3 = IsCitrus ; // false
In this example, IsCitrus
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3