TS 是 TypeScript 的缩写,是一种由微软开发的开源编程语言,它是 JavaScript 的一个超集,为 JavaScript 添加了类型系统和对 ES6+ 的支持。以下是关于 TypeScript 的详细介绍:
一、特点
-
类型系统:TypeScript 引入了类型注解,允许开发者为变量、函数参数、返回值等添加类型信息。这有助于在编译阶段发现潜在的类型错误,提高代码的健壮性和可维护性。例如:
javascriptlet message: string = "Hello, TypeScript!"; function add(a: number, b: number): number { return a + b; }
在 TypeScript 中,
type
和interface
都可以用来定义复杂数据类型,它们各有特点和适用场景,以下是详细介绍:
二、使用 type
定义复杂数据类型
- 基本语法:
javascript
type TypeName = {
property1: Type1;
property2: Type2;
// ...
};
- 定义对象类型:
javascript
type Person = {
name: string;
age: number;
address: {
street: string;
city: string;
};
};
-
定义联合类型 :
javascripttype StringOrNumber = string | number;
-
定义交叉类型 :
javascripttype Employee = { employeeId: number; } & Person;
-
定义泛型类型 :
javascripttype Container<T> = { value: T; };
三、使用
interface
定义复杂数据类型 -
基本语法 :
javascriptinterface InterfaceName { property1: Type1; property2: Type2; // ... }
-
定义对象类型 :
javascriptinterface Person { name: string; age: number; address: { street: string; city: string; }; }
-
定义类类型 :
javascriptinterface Person { name: string; age: number; greet(): void; } class Student implements Person { name: string; age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } greet() { console.log(`Hello, my name is ${this.name}`); } }
type
与interface
的区别与选择 -
区别:
-
type
是类型别名,可以为任何类型定义一个新的名字,包括基本类型、联合类型、交叉类型等;而interface
主要用于定义对象类型或类类型。 -
interface
可以被类实现(implements
),而type
不行。 -
interface
可以继承其他接口,而type
不行。 -
type
定义的类型可以使用交叉类型(&
)来组合多个类型,而interface
只能继承一个接口。
-
-
选择:
-
如果需要定义一个对象类型或类类型,并且希望使用继承或类实现,建议使用
interface
。 -
如果需要定义联合类型、交叉类型或泛型类型,或者需要为复杂类型定义别名,建议使用
type
。 -
在实际开发中,可以根据具体需求和团队编码规范来选择使用
type
或interface
。
-
四、 函数类型
在 TypeScript 中,函数类型 用于描述函数的参数类型和返回值类型。你可以通过类型别名(type
)或接口(interface
)来定义函数类型。
javascript
interface Api {
foo(): void;
bar(str: string): string;
}
function test(api: Api) {
api.foo();
const result = api.bar("hello");
console.log(result);
}
// 调用 test 函数
test({
foo() {
console.log('ok');
},
bar(str: string) {
return str.toUpperCase();
}
});
五、字面量与nullish类型
javascript
// 字面量类型:功能:输出一段文字(参数1),参数2决定文字的对齐方式
function printText(text: string, alignment: "left" | "right" | "center") {
console.log(text, alignment);
}
printText("Hello", "left");
printText("Hello", "center");
// nullish 类型 null undefined
function test(x?: string | null) {
// if (x !== null && x !== undefined)
// console.log(x.toUpperCase()); // 错误:x 可能为 null 或 undefined
console.log(x?.toUpperCase()); // 正确:使用可选链
}
test("hello");
test(null);
test();
六、泛型
javascript
interface Ref<T> {
value: T;
}
const r1: Ref<string> = { value: 'hello' };
const r2: Ref<number> = { value: 123 };
const r3: Ref<boolean> = { value: true };
function test1(n: string) {
return { value: n };
}
function test2(n: number) {
return { value: n };
}
function ref<T>(n: T): Ref<T> {
return { value: n };
}
const v1 = ref("hello"); // Ref<string>
const v2 = ref(123.3333); // Ref<number>
console.log(v2.value.toFixed(2)); // 输出: 123.33
七、class语法
一个基本的类定义包括类名、属性(成员变量)和方法(成员函数):
javascript
class Person {
// 类属性(成员变量)
firstName: string;
lastName: string;
// 构造函数
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
// 类方法(成员函数)
fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
}
继承
TypeScript 支持类的继承,可以使用 extends
关键字来实现:
javascript
class Employee extends Person {
employeeId: number;
constructor(firstName: string, lastName: string, employeeId: number) {
super(firstName, lastName); // 调用父类的构造函数
this.employeeId = employeeId;
}
work(): string {
return `${this.fullName()} is working`;
}
}
访问修饰符
TypeScript 提供了三种访问修饰符:
-
public
:公共的,可以在任何地方访问。 -
private
:私有的,只能在类内部访问。 -
protected
:受保护的,可以在类内部和子类中访问。javascriptclass Person { private name: string; constructor(name: string) { this.name = name; } public getName(): string { return this.name; } }
抽象类
抽象类是不能被实例化的类,通常用作基类:
javascriptabstract class Animal { abstract makeSound(): void; move(): void { console.log("Moving"); } } class Dog extends Animal { makeSound(): void { console.log("Bark"); } }
静态成员
类可以包含静态属性和方法,这些成员属于类本身,而不是类的实例:
javascriptclass Utils { static pi: number = 3.14; static calculateCircleArea(radius: number): number { return Utils.pi * radius * radius; } }
类表达式
类也可以作为表达式定义,这在定义匿名类时非常有用:
javascriptconst Animal = class { makeSound() { console.log("Some generic sound"); } }; const dog = new Animal(); dog.makeSound(); // 输出: Some generic sound
类类型
类本身可以作为类型使用:
javascriptlet person: Person; person = new Person("Alice", "Smith");
类与接口
类可以实现接口,接口定义了类必须遵循的结构:
javascriptinterface Greeting { greet(): string; } class Hello implements Greeting { greet(): string { return "Hello"; } }