1. 类型注解和类型推断
TypeScript最基本的功能就是为JavaScript提供类型系统。它支持两种方式来定义变量和函数的类型:类型注解和类型推断。
1.1 类型注解
类型注解指的是在变量或函数名后面使用冒号来指定类型。例如:
let age: number = 27;
function add(a: number, b: number): number {
return a + b;
}
在这个例子中,age被注解为一个number类型的变量,add函数被注解为接受两个number类型的参数并返回一个number类型的值。
类型注解的好处在于它可以提供更好的代码提示和错误检查。如果你在注解的变量或函数上使用了不符合类型的操作,TypeScript会在编译时给出错误提示。
1.2 类型推断
类型推断是指TypeScript自动推断变量和函数的类型。例如:
let age = 27;
function add(a: number, b: number) {
return a + b;
}
在这个例子中,age没有被注解为一个类型,但TypeScript会根据它的初始值自动推断出它是一个number类型的变量。同样,add函数没有被注解为一个返回值类型,但TypeScript会自动推断出它返回的是一个number类型的值。
类型推断的好处在于它可以减少代码量,让代码更加简洁。但是它也有缺点,因为它无法提供完全的类型检查。如果你需要更严格的类型检查,建议使用类型注解。
2. 接口和类型别名
TypeScript支持两种方式来定义自定义类型:接口和类型别名。
2.1 接口
接口是一种用来描述对象类型的方式。例如:
interface User {
name: string;
age: number;
}
let user: User = {
name: "Alice",
age: 27
};
在这个例子中,我们定义了一个User接口,它包含了一个name属性和一个age属性。我们可以使用该接口来定义一个user对象,该对象必须包含name和age属性,并且它们的类型分别为string和number。
接口的好处在于它可以提供更好的类型检查。如果你在user对象上使用了不符合接口定义的属性或类型,TypeScript会在编译时给出错误提示。
2.2 类型别名
类型别名是一种用来为类型定义一个名称的方式。例如:
type Point = {
x: number;
y: number;
};
let point: Point = {
x: 1,
y: 2
};
在这个例子中,我们定义了一个Point类型别名,它指代一个包含x和y属性的对象类型。我们可以使用该类型别名来定义一个point对象,该对象必须包含x和y属性,并且它们的类型分别为number。
类型别名的好处在于它可以让代码更加简洁。如果你需要多次使用同一个类型,使用类型别名可以让你更方便地引用该类型。
3. 泛型
泛型是一种用来创建可重用代码的方式,它可以让你在定义函数、类或接口时不指定具体类型,而是在使用时动态地指定类型。例如:
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("hello world");
在这个例子中,我们定义了一个identity函数,它接受一个类型为T的参数并返回一个类型为T的值。我们可以使用该函数来创建一个output变量,我们在调用identity函数时指定了string类型,所以output的类型也是string。
泛型的好处在于它可以让你写出更加灵活和可重用的代码。如果你需要编写一些通用的函数或类,使用泛型可以让你更加方便地处理不同类型的数据。