目录
1.简介
2.基础类型
2.1.布尔值(Boolean)
2.2. 数字(Number)
2.3.字符串(String)
2.4.数组(Array)
2.5.元组(Tuple)
2.6.枚举(Enum)
2.7.任意类型(Any)
2.8.空类型(Void)
2.8.空和未定义(Null和Undefined)
2.9.永不存在的值的类型(Never)
2.10.对象类型(Object)
3.基础语法
3.1.变量声明
3.2.函数
3.3.接口
3.4.类型别名
3.5.泛型
3.6.类型断言
4.相关链接
1.简介
TypeScript 是 JavaScript 的一个开源超集,添加了静态类型和面向对象的编程特性。它由微软开发,目的是提升大型 JavaScript 应用的开发效率和代码的可维护性。TypeScript 最终编译为纯 JavaScript,可以在任何支持 JavaScript 的环境中运行。
主要特点:
-
静态类型:TypeScript 允许为变量、函数参数和返回值指定类型,在编译时进行类型检查,从而减少运行时错误。
-
类型推断:TypeScript 可以自动推断变量的类型,即使没有显式声明,也能提供类型检查的好处。
-
接口:接口用于定义对象的结构和类型,确保对象符合预期的形状。
-
类和继承:支持面向对象编程,允许定义类、继承、修饰符等特性,使代码更具模块化和复用性。
-
模块化:支持 ES6 模块化规范,可以将代码拆分为独立的模块,提高代码的组织性和可维护性。
-
兼容性:TypeScript 是 JavaScript 的超集,任何合法的 JavaScript 代码也是合法的 TypeScript 代码。TypeScript 最终编译为 JavaScript,可以在任何 JavaScript 环境中运行。
2.基础类型
2.1.布尔值(Boolean)
布尔类型(Boolean):表示逻辑上的 true 或 false 值
let isDone: boolean = false;
2.2. 数字(Number)
数字类型(Number):表示所有数字类型,包括整数和浮点数。除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
2.3.字符串(String)
字符串类型(String):表示文本数据。可以使用双引号( " )或单引号( ' )表示字符串
let name: string = "bob";
name = 'smith';
可以使用模版字符串,它可以定义多行文本和内嵌表达式。 这种字符串是被反引号包围( `
),并且以${ expr }
这种形式嵌入表达式
let name: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ name }.
I'll be ${ age + 1 } years old next month.`;
2.4.数组(Array)
数组类型(Array):可以表示具有固定类型的数组。Typescript中有两种方式可以定义数组。
第一种,可以在元素类型后面接上 []
let list: number[] = [1, 2, 3];
第二种方式是使用数组泛型,Array<元素类型>
let list: Array<number> = [1, 2, 3];
2.5.元组(Tuple)
元组类型(Tuple):表示一个已知元素数量和类型的数组,各元素的类型不必相同。元组类型允许你在一个数组中存储不同类型的值,这在需要将不同类型的值组合在一起时非常有用。
// 声明一个元组类型
let x: [string, number];
// 初始化
x = ['hello', 10]; // OK
// 错误的初始化
x = [10, 'hello']; // Error
当访问一个已知索引的元素,会得到正确的类型:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 整数类型不存在 “substr” 方法
元组标签可以为元组中的元素提供更有意义的标签:
const person: [name: string, age: number] = ["Alice", 25];
console.log(person[0]); // "Alice"
console.log(person[1]); // 25
元组还支持可选元素和剩余元素:
// 可选元素
let tuple: [string, number?];
tuple = ["Alice"]; // 正确
tuple = ["Alice", 25]; // 也正确
// 剩余元素
let tuple2: [string, ...number[]];
tuple2 = ["Alice", 25, 30, 35]; // 正确
2.6.枚举(Enum)
枚举类型(Enum):使用枚举类型可以为一组数值赋予友好的名字。
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
默认情况下,从0
开始为元素编号。 你也可以手动的指定成员的数值。 例如,我们将上面的例子改成从 1
开始编号:
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
或者,全部都采用手动赋值:
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName); // 显示'Green'因为上面代码里它的值是2
2.7.任意类型(Any)
任意类型(Any):表示任意类型的值,适用于动态内容的场景。
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // 也可以是布尔类型
2.8.空类型(Void)
空类型(Void):表示没有任何类型。当一个函数没有返回值时,你通常会见到其返回值类型是 void。
function logMessage(): void {
console.log("This is a log message");
}
2.8.空和未定义(Null和Undefined)
空和未定义(Null和Undefined) :TypeScript里,undefined
和null
两者各自有自己的类型分别叫做undefined
和null
。
let u: undefined = undefined;
let n: null = null;
2.9.永不存在的值的类型(Never)
永不存在的值的类型(Never):表示的是那些永不存在的值的类型。
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
2.10.对象类型(Object)
对象类型(Object):表示非原始类型,也就是除number
,string
,boolean
,symbol
,null
或undefined
之外的类型。
let obj: object = { name: "Alice", age: 25 };
3.基础语法
TypeScript 的基本语法在 JavaScript 的基础上增加了类型注解和一些高级特性。以下是 TypeScript 的一些基本语法介绍:
3.1.变量声明
TypeScript 的变量声明与 JavaScript 类似,但它引入了类型注解,以确保变量只能赋值为指定类型的值,使得代码更加严格和可维护。
let name: string = "Alice";
const age: number = 25;
let isStudent: boolean = true;
3.2.函数
可以为函数的参数和返回值添加类型注解:
function add(x: number, y: number): number {
return x + y;
}
let result = add(5, 3); // 结果为 8
Typescript中支持可选参数和默认参数,可选参数使用 ?
标记,默认参数可以在参数声明时赋值:
// 可选参数
function buildName(firstName: string, lastName?: string): string {
return lastName ? `${firstName} ${lastName}` : firstName;
}
let name1 = buildName("Alice"); // "Alice"
let name2 = buildName("Alice", "Smith"); // "Alice Smith"
// 默认参数
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}`;
}
let greet1 = greet("Alice"); // "Hello, Alice"
let greet2 = greet("Alice", "Hi"); // "Hi, Alice"
Typescript中支持函数重载,函数重载允许同一个函数名有多个函数定义,具体实现由最后一个函数体定义:
function getInfo(name: string): string;
function getInfo(age: number): string;
function getInfo(value: any): string {
if (typeof value === "string") {
return `Name: ${value}`;
} else if (typeof value === "number") {
return `Age: ${value}`;
}
return "";
}
let info1 = getInfo("Alice"); // "Name: Alice"
let info2 = getInfo(25); // "Age: 25"
可以为函数定义类型:
type Add = (x: number, y: number) => number;
let add: Add = (x, y) => x + y;
3.3.接口
接口用于定义对象的形状。
interface Person {
firstName: string;
lastName: string;
}
function greet(person: Person) {
return `Hello, ${person.firstName} ${person.lastName}`;
}
let user = { firstName: "John", lastName: "Doe" };
console.log(greet(user)); // Hello, John Doe
接口中的属性可以是可选的,在属性名后加 ?
标记。
interface Person {
firstName: string;
lastName?: string;
}
function greet(person: Person) {
if (person.lastName) {
return `Hello, ${person.firstName} ${person.lastName}`;
} else {
return `Hello, ${person.firstName}`;
}
}
let user1 = { firstName: "John" };
let user2 = { firstName: "Jane", lastName: "Doe" };
console.log(greet(user1)); // Hello, John
console.log(greet(user2)); // Hello, Jane Doe
使用 readonly
关键字定义只读属性。
interface Point {
readonly x: number;
readonly y: number;
}
let point: Point = { x: 10, y: 20 };
// point.x = 5; // 不能给x属性赋值,因为它是只读属性.
使用索引签名来定义可能存在的额外属性。
interface Person {
firstName: string;
lastName?: string;
[propName: string]: any;
}
let user: Person = { firstName: "John", age: 30 };
接口不仅可以描述对象,还可以描述函数类型。
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function (src, sub) {
return src.indexOf(sub) > -1;
};
接口可以用于描述具有索引签名的类型。
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Alice"];
let myStr: string = myArray[0];
接口可以用来描述类的公共部分。
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}
}
3.4.类型别名
使用 type
关键字可以为类型创建别名。
下面是基础类型、联合类型和对象类型。
// 基本类型
type Name = string;
// 联合类型
type StringOrNumber = string | number;
// 对象类型
type Person = {
firstName: string;
lastName: string;
age: number;
};
let myName: Name = "Alice";
let value1: StringOrNumber = "Hello";
let user: Person = {
firstName: "John",
lastName: "Doe",
age: 30,
};
交叉类型:
type Person = {
name: string;
};
type Employee = {
employeeId: number;
};
type EmployedPerson = Person & Employee;
let employee: EmployedPerson = {
name: "Alice",
employeeId: 1234,
};
数组类型:
type StringArray = string[];
let names: StringArray = ["Alice", "Bob", "Charlie"];
元组类型:
type NameAndAge = [string, number];
let person: NameAndAge = ["Alice", 25];
函数类型:
type GreetFunction = (name: string) => string;
let greet: GreetFunction = (name: string) => {
return `Hello, ${name}`;
};
3.5.泛型
泛型(Generics)是 TypeScript 中的一种功能强大的特性,用于创建可重用的组件。通过使用泛型,可以创建一个可以适用于多个类型的函数、类或接口,而不是指定单一类型。泛型使代码更灵活和可重用,同时保留了类型安全性。
泛型函数,以下是一个简单的泛型函数示例,它可以接受任意类型的参数并返回相同类型的值:
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString"); // T 被推断为 'string'
let output2 = identity<number>(42); // T 被推断为 'number'
泛型变量,在函数内部使用泛型变量,可以保持参数类型的一致性:
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
let output = loggingIdentity<number>([1, 2, 3]);
泛型接口,允许你定义一组类型安全的操作,而这些操作可以适用于多种类型:
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;
泛型约束,有时需要约束泛型类型,要求它们符合某些条件。可以通过接口来实现:
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no error
return arg;
}
loggingIdentity({ length: 10, value: 3 });
3.6.类型断言
类型断言(Type Assertions)是 TypeScript 中的一种机制,用于告诉编译器你比它更清楚某个值的类型。类型断言不会对运行时的值进行任何检查或重构,它仅存在于编译阶段,帮助你避免类型检查错误和提高代码的可读性。类型断言的语法有两种:
- 尖括号语法
- as语法
尖括号语法。
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
console.log(strLength); // 输出: 16
as语法 ,在 JSX 中推荐使用,因为尖括号语法会与 JSX 语法冲突。
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
console.log(strLength); // 输出: 16
类型断言是 TypeScript 中处理类型检查的一种重要工具,允许你在编译阶段控制类型检查的结果。通过类型断言,可以解决类型推断不足的问题,处理联合类型,以及在必要时强制转换类型。
4.相关链接
Typescript中文网