类型注解允许你明确指定变量的类型。
let isDone: boolean = false; // 布尔类型
let age: number = 25; // 数字类型
let name: string = "Alice"; // 字符串类型
接口定义了一个对象的结构。
interface Person {
firstName: string;
lastName: string;
age: number;
}
let john: Person = {
firstName: "John",
lastName: "Doe",
age: 30
};
类提供了面向对象编程的基础。
class Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
move(): void {
return `${this.name} moves.`;
}
}
class Snake extends Animal {
constructor(name: string) {
super(name);
}
move(): void {
return `${this.name} slides.`;
}
}
let sam = new Snake("Sammy the Python");
console.log(sam.move()); // 输出: "Sammy the Python slides."
泛型允许你创建可重用的组件,这些组件可以支持多种类型。
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString"); // 返回类型为string
let output2 = identity<number>(123); // 返回类型为number
枚举类型用于定义命名的数字常量集合。
enum Color {
Red,
Green,
Blue
}
let c: Color = Color.Green;
当你比TypeScript更确定一个值的类型时,可以使用类型断言。
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// 或者使用 as 关键字
let strLength2: number = (someValue as string).length;
模块允许你将代码分割到不同的文件中,并导出和导入功能。
module.ts
export function sayHello(name: string) {
return `Hello, ${name}!`;
}
main.ts
import { sayHello } from './module';
let greeting = sayHello("World");
console.log(greeting); // 输出: "Hello, World!"
这通常用于为JavaScript库提供TypeScript类型支持。
exampleLib.d.ts
declare module "exampleLib" {
export function doSomething(value: string): void;
}
main.ts
import * as exampleLib from "exampleLib";
exampleLib.doSomething("Hello from TypeScript!");
允许你为函数提供多个类型签名。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === "number") {
return x * -1;
} else if (typeof x === "string") {
return x.split("").reverse().join("");
}
}
console.log(reverse(123)); // 输出: -123
console.log(reverse("hello")); // 输出: "olleh"
交叉类型是将多个类型合并为一个类型。这允许你创建一个对象,该对象具有多个类型的属性。
type Combined = Type1 & Type2 & Type3;
联合类型表示一个值可以是几种类型之一。
function handleValue(value: string | number) {
if (typeof value === "string") {
// 处理字符串
} else if (typeof value === "number") {
// 处理数字
}
}
索引类型允许你定义对象的键和值的类型。
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Alice", "Bob", "Charlie"];
只读属性确保属性只能被初始化一次,然后就不能被重新赋值了。
interface Person {
readonly firstName: string;
lastName: string;
}
let john: Person = {
firstName: "John",
lastName: "Doe"
};
// john.firstName = "Jane"; // 这行代码会报错,因为 firstName 是只读的
john.lastName = "Smith"; // 这是允许的
字符串字面量类型允许你指定一个变量只能是几个特定的字符串值之一。
type Easing = "ease-in" | "ease-out" | "ease-in-out";
function animate(element: HTMLElement, duration: number, easing: Easing) {
// ...
}
animate(element, 1000, "ease-in"); // 正确
animate(element, 1000, "zoom"); // 错误,因为 "zoom" 不是 Easing 类型的一部分
映射类型允许你根据已有的类型创建新的类型,并对每个属性应用某种转换。
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface Person {
name: string;
age: number;
}
const partialPerson: Partial<Person> = {
name: "Alice"
// age 是可选的,可以省略
};
条件类型允许你根据条件来定义类型的形状。
type TypeOf<T> = {
[P in keyof T]: T[P] extends Function ? 'method' : 'property';
};
interface Person {
name: string;
greet: () => void;
}
type PersonTypes = TypeOf<Person>;
// PersonTypes 类型等同于 { name: 'property'; greet: 'method'; }
泛型约束允许你为泛型参数设置一些条件,确保它们满足特定的类型。
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
let person = { name: "Alice", age: 30 };
console.log(getProperty(person, "name")); // 输出: "Alice"
类型别名和接口在 TypeScript 中都用于定义类型的形状,但它们有一些区别:
当你确定一个值不可能是 null
或 undefined
时,可以使用非空断言操作符 !
。
let user: User | null = getUser();
console.log(user!.name); // 断言 user 不是 null 或 undefined