enum Http {
GET = "GET",
POST = "POST",
PUT = "PUT"
}
const method:Http = Http.POST
// Http["POST"] → undefined 取不到
const enum 常量枚举
TypeScript复制代码
const enum Sex {Man=1,Woman=2}
let x = Sex.Man
//编译后:let x = 1,不生成Sex对象
//vite/isolatedModules:true 下用const enum会报错,换成普通enum
现在很多项目不用 enum,用 as const
TypeScript复制代码
const Status = {
OK:1,
ERR:2
} as const
type StatusType = typeof Status[keyof typeof Status]
自定义类型
可以更加灵活的限制类型
TypeScript复制代码
// 自定义一个类型,只能是1、2、3中的一个
type Grade = 1 | 2 | 3
// 自定义一个类型,包含id和grade两个属性
type Student = {
id: string
grade: Grade
}
let s1: Student
let s2: Student
s1 = {
id:"1001",
grade:1
}
s2 = {
id:"1002",
grade:2
}
二、TypeScript 面向对象知识详解
抽象类
常规类
TypeScript复制代码
class Person {
name: string
age: number
constructor(name:string,age:number){
this.name = name
this.age = age
}
}
const p1 = new Person('张三',18)
const p2 = new Person('李四',19)
console.log(p1)
console.log(p2)
继承
TypeScript复制代码
// Person类
class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
}
// Teacher类继承Person
class Teacher extends Person {
constructor(name: string, age: number) {
super(name, age)
}
}
// Student类继承Person
class Student extends Person {
constructor(name: string, age: number) {
super(name, age)
}
}
// Person实例
const p1 = new Person('周杰伦',38)
// Student实例
const s1 = new Student('张同学',18)
const s2 = new Student('李同学',20)
// Teacher实例
const t1 = new Teacher('刘⽼师',40)
const t2 = new Teacher('孙⽼师',50)
抽象类
不能去实例化,但可以被别人继承,抽象类里有抽象方法
TypeScript复制代码
// Person(抽象类)
abstract class Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
abstract speak(): void
}
// Teacher类继承Person
class Teacher extends Person {
// 构造器
constructor(name: string,age: number){
super(name,age)
}
// ⽅法
speak(){
console.log('你好!我是⽼师:',this.name)
}
}
// Student类继承Person
class Student extends Person {
// 构造器
constructor(name: string,age: number){
super(name,age)
}
// ⽅法
speak(){
console.log('你好!我是学生:',this.name)
}
}
// Person实例
// const p1 = new Person('周杰伦',38)
接口
接口用于限制⼀个类中包含哪些属性和方法
TypeScript复制代码
// Person接口
interface Person {
name: string
age: number
speak(): void
}
// Teacher类实现Person接口
class Teacher implements Person {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak(): void {
console.log('你好!我是老师:', this.name)
}
}
接口是可以重复声明的
TypeScript复制代码
interface PersonInter {
name: string
age: number
}
interface PersonInter {
speak(): void
}
class Person implements PersonInter {
name: string
age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
speak(): void {
console.log('你好!我是', this.name)
}
}
区别分析
与自定义类型的区别
接口可以当自定义类型使用,还可以限制类的结构
TypeScript复制代码
// 1.定义接口
interface User {
name:string
say():void
}
// 类用implements实现接口
class U implements User{
name = "张三"
say(){}
}
// 接口重复定义自动合并
interface User{age?:number}
与抽象类的区别
接口只能有抽象方法,使用implements关键字去实现接口
抽象类除了抽象方法还可以有普通方法 ,使用extends关键字去继承抽象类
TypeScript复制代码
interface I {
fn():void // 只有抽象,不能写方法体
}
class A implements I{
fn(){}
}
abstract class Abs{
abstract fn():void //抽象
hello(){console.log(1)} //已有实现的普通方法
}
class B extends Abs{
fn(){}
}
属性修饰符
修饰符
中文含义
可修改 / 访问范围
readonly
只读属性
仅可在声明时 / 构造函数内赋值,属性无法修改
public
公开的
可以在类内部、子类、外部对象中访问和修改
protected
受保护的
可以在类内部、子类中访问和修改,外部对象无法访问
private
私有的
仅可以在类内部访问和修改,子类、外部对象均无法访问
readonly
TypeScript复制代码
class User {
readonly id: number;
name: string;
constructor(id: number, name: string) {
this.id = id; // 仅构造函数内可给readonly赋值
this.name = name;
}
}
const u = new User(1, "张三");
u.id = 2; // 报错:readonly 无法修改
u.name = "李四"; // 正常修改
public
TypeScript复制代码
class User {
public name: string;
constructor(name: string) {
this.name = name;
}
}
const u = new User("张三");
u.name = "李四"; // 外部可直接修改
protected
TypeScript复制代码
class User {
protected name: string;
constructor(name: string) {
this.name = name;
}
}
class VipUser extends User {
changeName() {
this.name = "VIP李四"; // 子类可修改
}
}
const u = new User("张三");
u.name = "李四"; // 报错:外部对象无法访问
private
TypeScript复制代码
class User {
private name: string;
constructor(name: string) {
this.name = name;
}
changeName() {
this.name = "李四"; // 仅类内部可修改
}
}
class VipUser extends User {
test() {
this.name = "VIP"; // 报错:子类无法访问
}
}
const u = new User("张三");
u.name = "李四"; // 报错:外部对象无法访问
泛型
定义⼀个函数或类时,有些情况下无法确定其中要使用的具体类型,此时就需要泛型了
<T> 就是泛型,(不⼀定非叫 T ),设置泛型后即可在函数中使用 T 来表示该类型
TypeScript复制代码
function test<T>(arg: T): T {
return arg
}
// 不指明类型,会自动推导类型
test(10)
// 指明类型,会强制转换为指定类型
test<number>(10)
泛型可以写多个
TypeScript复制代码
function test<T, U>(a: T, b: U): T {
return a
}
// 调用时指定类型参数
test<number, string>(10, 'hello')
类中同样可以使用泛型
TypeScript复制代码
class MyClass<T>{
prop: T;
constructor(p: T) {
this.prop = p;
}
getProp(): T {
return this.prop;
}
}
也可以对泛型的范围进行约束
TypeScript复制代码
interface Demo{
length: number
}
function test<T extends Demo>(arg: T): number {
return arg.length
}
// 类型number没有length属性,不能赋值给类型Demo的参数类型
test(10)
// 类型{name:string}的参数不能赋值给类型Demo的参数类型
test({name:'张三'})
// 这两个就是正确的
test('123')
test({name:'张三',length:18})