边写边练 跟着一个个例子走 快速学习入门typescript

跟着一个个例子走

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.com/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.com/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 方法来处理成功和失败的情况。在成功时,我们打印获取到的用户对象到控制台。在失败时,我们打印错误信息到控制台。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值