跟着一个个例子走
1. 声明变量和类型
let a: number = 10;
let b: string = 'Hello TypeScript';
let c: boolean = true;
这些代码声明了三个变量,分别是数字类型、字符串类型和布尔类型。在 TypeScript 中,可以通过在变量名后面使用冒号来声明变量的类型。
2. 函数
function add(a: number, b: number): number {
return a + b;
}
let result = add(2, 3);
console.log(result); // 输出 5
这个例子定义了一个接收两个数字类型参数并返回数字类型的函数。在调用函数时,需要传递正确的参数类型。如果传递错误的参数类型,TypeScript 编译器将会报错。
3. 接口
interface Person {
firstName: string;
lastName: string;
age: number;
}
function sayHello(person: Person) {
console.log(`Hello ${person.firstName} ${person.lastName}`);
}
let person = {
firstName: 'John',
lastName: 'Doe',
age: 30,
};
sayHello(person);
这个例子定义了一个名为 Person 的接口,它包含了 firstName、lastName 和 age 三个属性。在函数中,我们通过 person 参数使用了 Person 接口,当我们调用函数时,需要传递一个包含 firstName、lastName 和 age 属性的对象。
4. 类
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name: string) {
super(name);
}
speak() {
console.log(`${this.name} barks.`);
}
}
let dog = new Dog('Buddy');
dog.speak(); // 输出 "Buddy barks."
这个例子定义了一个 Animal 类和一个继承自 Animal 的 Dog 类。Animal 类有一个名为 name 的属性和一个 speak 方法。Dog 类继承了 Animal 类,并重写了 speak 方法。在创建 Dog 实例时,需要传递一个名为 Buddy 的字符串参数,然后可以通过调用 speak 方法来输出 Dog 的声音。
5. 枚举
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
console.log(c); // 输出 1
这个例子定义了一个名为 Color 的枚举类型,它包含了三个值:Red、Green 和 Blue。在定义枚举类型时,如果没有给每个成员设置具体的值,则 TypeScript 会自动给每个成员设置一个递增的数字值,从 0 开始。在这个例子中,Color.Green 的值为 1。
6. 泛型
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>('Hello TypeScript');
let output2 = identity<number>(100);
console.log(output1); // 输出 "Hello TypeScript"
console.log(output2); // 输出 100
这个例子定义了一个名为 identity 的泛型函数,它接收一个类型参数 T 和一个值参数 arg,然后返回 arg 的值。在调用泛型函数时,需要传递类型参数,以告诉 TypeScript 在函数中使用哪个类型。在这个例子中,我们使用了字符串类型和数字类型。
7. 类型断言
let someValue: any = 'Hello TypeScript';
let strLength1: number = (<string>someValue).length;
let strLength2: number = (someValue as string).length;
console.log(strLength1); // 输出 17
console.log(strLength2); // 输出 17
这个例子定义了一个名为 someValue 的 any 类型变量,并将其赋值为一个字符串。然后,我们使用类型断言将其转换为字符串类型,并获取其长度。在 TypeScript 中,有两种类型断言的写法:一种是在值前使用尖括号,另一种是在值前使用 as 关键字。在这个例子中,我们使用了这两种写法。
8. 类型别名
type Name = string;
type Age = number;
interface Person {
name: Name;
age: Age;
}
let person: Person = {
name: 'John Doe',
age: 30,
};
这个例子定义了两个类型别名:Name 和 Age。然后,我们使用这两个类型别名来定义一个名为 Person 的接口,并使用它来定义一个 person 变量。
9. 可选属性
interface Person {
name: string;
age?: number;
}
let person1: Person = { name: 'John Doe' };
let person2: Person = { name: 'Jane Doe', age: 30 };
这个例子定义了一个名为 Person 的接口,它包含了一个必需的 name 属性和一个可选的 age 属性。在创建 person1 和 person2 变量时,我们可以选择传递 age 属性或不传递。
10. 只读属性
interface Point {
readonly x: number;
readonly y: number;
}
let p: Point = { x: 10, y: 20 };
console.log(p.x); // 输出 10
// 不能修改只读属性
// p.x = 5; // 报错:Cannot assign to 'x' because it is a read-only property.
这个例子定义了一个名为 Point 的接口,它包含了两个只读属性 x 和 y。在创建 p 变量时,我们必须给 x 和 y 属性设置初始值,并且不能再修改它们的值。
11. 函数重载
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {
return a + b;
}
let result1 = add(2, 3);
let result2 = add('Hello', 'TypeScript');
console.log(result1); // 输出 5
console.log(result2); // 输出 "HelloTypeScript"
这个例子定义了一个 add 函数,它有两个重载版本,一个接收两个数字类型参数并返回数字类型,另一个接收两个字符串类型参数并返回字符串类型。在调用函数时,TypeScript 编译器会根据传递的参数类型选择正确的重载版本。
12. 类型推断
let num = 10;
// num = 'Hello TypeScript'; // 报错:Type '"Hello TypeScript"' is not assignable to type 'number'.
let arr = [1, 2, 3];
// arr.push('Hello'); // 报错:Argument of type '"Hello"' is not assignable to parameter of type 'number'.
let obj = { name: 'John', age: 30 };
// obj.gender = 'male'; // 报错:Property 'gender' does not exist on type '{ name: string; age: number; }'.
这个例子演示了 TypeScript 的类型推断功能。在定义变量时,如果没有显式指定类型,TypeScript 编译器会根据初始值推断出变量的类型。在这个例子中,变量 num 被推断为数字类型、变量 arr 被推断为数字类型数组、变量 obj 被推断为包含 name 和 age 属性的对象。如果我们尝试给这些变量赋予错误的类型的值,TypeScript 编译器会报错。
13. 泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(`Length of ${arg} is ${arg.length}`);
return arg;
}
loggingIdentity('Hello TypeScript');
// 输出 "Length of Hello TypeScript is 17"
loggingIdentity([1, 2, 3]);
// 输出 "Length of 1,2,3 is 3"
这个例子定义了一个名为 Lengthwise 的接口,它包含了一个 length 属性。然后,我们定义了一个泛型函数 loggingIdentity,它接收一个类型参数 T,它必须满足 Lengthwise 接口的约束条件。在函数中,我们使用了 arg 参数的 length 属性,并将其打印到控制台。在调用 loggingIdentity 函数时,我们传递了两个参数:一个字符串和一个数字数组。这两个参数都满足 Lengthwise 接口的约束条件,因此可以被成功地传递给函数。
14. 构造函数
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return `Hello, ${this.greeting}!`;
}
}
let greeter = new Greeter('TypeScript');
console.log(greeter.greet()); // 输出 "Hello, TypeScript!"
这个例子定义了一个名为 Greeter 的类,它包含了一个名为 greeting 的属性和一个名为 greet 的方法。在类的构造函数中,我们传递了一个名为 message 的字符串参数,并将其赋值给 greeting 属性。在创建 greeter 变量时,我们使用 new 关键字和 Greeter 类的构造函数来创建一个新的 Greeter 对象,并将字符串 “TypeScript” 传递给构造函数。然后,我们调用 greet 方法,并将其输出到控制台。
15. 接口继承
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square = {} as Square;
square.color = 'blue';
square.sideLength = 10;
console.log(square.color); // 输出 "blue"
console.log(square.sideLength); // 输出 10
这个例子定义了一个名为 Shape 的接口,它包含了一个名为 color 的属性。然后,我们定义了一个名为 Square 的接口,它继承自 Shape 接口,并添加了一个名为 sideLength 的属性。在创建 square 变量时,我们将其类型设置为 Square 接口,并通过对象字面量初始化它的属性。由于 Square 接口继承自 Shape 接口,因此它可以访问 Shape 接口的属性,如 color 属性。
16. 交叉类型
interface Person {
name: string;
}
interface Employee {
company: string;
}
type PersonAndEmployee = Person & Employee;
let personAndEmployee: PersonAndEmployee = {
name: 'John Doe',
company: 'Acme Inc.',
};
console.log(personAndEmployee.name); // 输出 "John Doe"
console.log(personAndEmployee.company); // 输出 "Acme Inc."
这个例子定义了两个接口:Person 和 Employee,然后使用交叉类型将它们合并成一个新的类型 PersonAndEmployee。在创建 personAndEmployee 变量时,我们使用了 PersonAndEmployee 类型,并初始化它的属性。由于 PersonAndEmployee 类型是 Person 和 Employee 类型的交叉类型,因此它包含了两个接口的所有属性。
17. 空值
function warnUser(): void {
console.log('This is a warning message.');
}
warnUser();
这个例子定义了一个名为 warnUser 的函数,它不返回任何值(void)。在函数中,我们只是简单地将一条警告消息打印到控制台。在调用 warnUser 函数时,它不会返回任何值,因此不能将其赋值给变量。
18. 可索引类型
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ['Hello', 'TypeScript'];
console.log(myArray[0]); // 输出 "Hello"
console.log(myArray[1]); // 输出 "TypeScript"
这个例子定义了一个名为 StringArray 的接口,它包含了一个索引签名,它的键是数字类型,值是字符串类型。然后,我们定义了一个 myArray 变量,并将其类型设置为 StringArray 接口。在创建 myArray 变量时,我们使用了一个字符串数组来初始化它。由于 StringArray 接口具有数字索引签名,因此可以使用方括号来访问 myArray 变量中的元素。
19.联合类型
function printId(id: number | string): void {
console.log(`ID is ${id}`);
}
printId(123);
printId('abc');
这个例子定义了一个名为 printId 的函数,它接收一个类型为 number 或 string 的参数 id,并将其打印到控制台。在调用 printId 函数时,我们可以传递数字或字符串类型的参数,因为它们都是 number | string 类型的变量。
20. 可选链式调用
interface User {
name: string;
address?: {
city: string;
country?: string;
};
}
let user1: User = { name: 'John Doe' };
let user2: User = { name: 'Jane Doe', address: { city: 'New York', country: 'USA' } };
console.log(user1.address?.city); // 输出 undefined
console.log(user2.address?.country); // 输出 "USA"
这个例子定义了一个名为 User 的接口,它包含了一个必需的 name 属性和一个可选的 address 属性,它的值是一个包含 city 和 country 属性的对象。在创建 user1 和 user2 变量时,我们传递了不同的参数,其中 user2 包含了 address 属性。在访问 user1 和 user2 变量的 address 属性时,我们使用了可选链式调用运算符 ?,它可以确保如果 address 属性不存在时不会引发错误。
21.never 类型
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}
这个例子定义了两个函数,它们都返回 never 类型。函数 throwError 接收一个字符串参数 message,并抛出一个包含该字符串的错误。由于 throwError 函数永远不会正常返回,因此它的返回类型被标记为 never。
函数 infiniteLoop 包含一个无限循环,它永远不会停止。由于 infiniteLoop 函数永远不会正常返回,因此它的返回类型也被标记为 never。
22.Promise 类型
function fetchData(url: string): Promise<string> {
return fetch(url)
.then(response => response.text())
.catch(error => {
console.error(error);
return '';
});
}
fetchData('https://jsonplaceholder.typicode/todos/1')
.then(data => console.log(data))
.catch(error => console.error(error));
这个例子定义了一个名为 fetchData 的函数,它接收一个 URL 字符串作为参数,并返回一个 Promise< string > 类型的对象。在函数内部,我们使用 fetch 函数来获取指定 URL 的数据,并将其转换为文本格式。如果请求失败,则打印错误信息并返回空字符串。
在调用 fetchData 函数时,它返回一个 Promise 对象,我们可以使用 then 和 catch 方法来处理成功和失败的情况。在成功时,我们打印获取到的数据到控制台。在失败时,我们打印错误信息到控制台。
23.async/await
async function fetchUser(id: number): Promise<User> {
const response = await fetch(`https://jsonplaceholder.typicode/users/${id}`);
const user = await response.json();
return user as User;
}
interface User {
id: number;
name: string;
email: string;
}
fetchUser(1)
.then(user => console.log(user))
.catch(error => console.error(error));
这个例子定义了一个名为 fetchUser 的异步函数,它接收一个数字类型的参数 id,并返回一个 Promise< User > 类型的对象。在函数内部,我们使用 await 关键字来等待 fetch 函数的响应,并使用 await 关键字将其转换为 JSON 格式。最后,我们将获取到的 JSON 数据转换为 User 类型的对象,并返回它。
在调用 fetchUser 函数时,它返回一个 Promise 对象,我们可以使用 then 和 catch 方法来处理成功和失败的情况。在成功时,我们打印获取到的用户对象到控制台。在失败时,我们打印错误信息到控制台。
更多推荐
边写边练 跟着一个个例子走 快速学习入门typescript
发布评论