这是我参与「第四届青训营 」笔记创作活动的的第24天
class类
- 声明成员age,类型为number(没有初始值)
- 声明成员gender,并设置初始值,此时,可省略类型注解(TS类型推论为string类型)
class Person {
age: number
gender = '男'
//gender: string = '男'
}
const p = new Person()
p.age
p.gender
- 构造函数:构造函数不需要返回值类型
class Person {
age: number
gender: string
constructor(age: number, gender: string) {
this.age = age
this.gender = gender
}
}
const p = new Person(18, '男')
console.log(p.age, p.gender)
- 实例方法
class Point {
x = 1
y = 2
scale(n: number) {
this.x *=n
this.y *=n
}
}
const p = new Point()
p.scale(10)
console.log(p.x, p.y)
- 继承(extends)
class Animal {
move() { console.log('Moving along!')}
}
class Dog extends Animal {
bark() { console.log('汪!')}
}
const dog = new Dog()
dog.move()
dog.bark()
- 继承(implements)
interface Singable {
sing(): void
}
class Person implements Singable {
sing() {
console.log('小苹果')
}
}
- 可见性
public(公有的):公有成员可以被任何地方访问,默认可见性(可直接省略)
protected(受保护的):仅对其声明所在的类和子类(非实例对象)中可见
private(私有的):旨在当前类可见,实例对象以及子类都不可见
class Animal {
public move() { console.log('Moving along!')}
}
class Animal {
protected move() {console.log('走两步')}
run() {
this.move()
console.log('跑起来')
}
}
const a = new Animal()
//a.move()不能使用
class Dog extends Animal {
bark() {
this.move()
console.log('汪!')
}
}
class Animal {
private run() {
console.log('Animal内部辅助函数')
}
protected move() {
this.run()
}
}
- 只读修饰符
用来防止在构造函数之外对属性进行赋值
只能修饰属性不能修饰方法
readonly关键字后的属性不加类型注解的话,则类型为字面量类型
接口或者{}表示的对象类型,也可以使用readonly
class Person {
readonly age: number = 18
constructor(age: number) {
this.age = age
}
//错误演示:
//readonly setAge() {
// this.age = 20
//}
}
interface IPerson {
readonly name: string
}
let obj: {readonly name: string } = {
name: 'jack'
}
类型兼容性
- 对象类型:y的成员与x相同,则x兼容y
class Piont { x: number; y: number }
class Piont3D { x: number; y: number; z: number }
const p: Point = new Point3D()
- 接口类型:class和interface之间可以兼容
interface Point { x: number; y: number }
interface Point2D { x: number; y: number }
interface Point3D { x: number; y: number; z: number }
let p1: Point
let p2: Point2D = p1
let p3: Point3D
p2 = p3
interface Point2D { x: number; y: number }
class Point3D { x: number; y: number; z: number }
let p3: Point2D = new Point3D()
- 函数之间的兼容性
参数数量:参数多的兼容参数少的,或者说参数少的可以赋值给参数多的
type F1 = (a: number) => void
type F2 = (a: number, b: number) => void
let f1: F1
let f2: F2 = f1
参数类型:相同位置的参数类型要相同或兼容
interface Point2D { x: number; y: number }
interface Point3D { x: number; y: number; z: number }
type F2 = (p: Point2D) => void
type F3 = (p: Point3D) => void
let f2: F2
let f3: F3 = f2
f2 = f3
- 返回值类型
如果返回值类型是原始类型,此时两个类型要相同
如果返回值类型是对象类型,此时成员多的可以赋值给成员少的
//原始类型:
type F5 = () => string
type F6 = () => string
let f5: F5
let f6: F6
f5 = f6
//f6 = f5
//对象类型:
type F7 = () => { name: string }
type F8 = () => { name: string; age:number }
let f7: F7
let f8: F8
f7 = f8
交叉类型
interface Person {
name: string
say(): number
}
interface Contact { phone: string }
type PersonDetail = Person & Contact
let obj: PersonDetail = {
name: 'jack',
phone: '133......',
say() {
return 1
}
}
交叉类型和接口继承的对比
接口继承会报错,交叉类型不会报错
interface A {
fn: (value: number) => string
}
interface B {
fn: (value: string) = string
}
type C = A & B
fn: (value: string | number) => string
泛型
- 基本使用
在函数名称的后面添加<>,尖括号中添加类型变量
类型变量,一种特殊类型的变量,它处理类型而不是值
给类型变量相当于一个类型容器,能偶捕获用户提供的类型
function id<Type>(value: Type): Type {
return value
}
const num = id<string>('a')
- 简化
类型参数推断机制
当无法推断是,就需要传入类型参数
function id<Type>(value: Type): Type {
return value
}
const num = id(100)
- 泛型约束
添加约束,缩窄类型取值范围
创建描述约束的接口,要求提供某某属性
interface ILength { length: number }
function id<Type extends ILength>(value: Type): Type {
console.log(value.length)
return value
}
多个泛型变量的情况
Key只能是Type所有键中的任意一个,或者是只能访问对象中存在的属性
function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key]
}
let person = { name: 'jack', age: 18 }
getProp(person, 'name')
- 泛型接口
interface IdFunc<Type> {
id: (value: Type) => Type
ids: () => Type[]
}
Let obj: IdFunc<number> = {
id(value) {
return value
},
ids() {
return [1,3,5]
}
}
- 泛型类
class GenericNumber<NumType> {
defaultValue: NumType
add: (x: NumType, y: NumType) => NumType
}
const myNum = new GenericNumber<number>()
myNum.defaultValue = 10
- Partial:将Type的所有属性设置为可选
interface Props {
id: string
children: number[]
}
type PartialProps = Partial<Props>
- readonly:只读
interface Props {
id: string
children: number[]
}
type ReadonlyProps = Readonly<Props>
- Pick:Type中选择一组属性来构造新类型
interface Props {
id: string
title: string
children: number[]
}
type PickProps = Pick<Props, 'id'|'title'>
- Record:构造一个对象类型,属性键位Keys,属性类型位Type
type RecordObj = Record<'a'|'b'|'c',srting[]>
let obj: RecordObj = {
a: ['a'],
b: ['b'],
c: ['c']
}
索引签名类型
interface AnyObject {
[key: string]: number
}
Let obj: AnyObject = {
a: 1,
abc: 124,
}
映射类型
基于旧类型创建新类型
只能在类型别名中使用,不能在接口中使用
type Propkeys = 'x'|'y'|'z'
type Type1 = { x: number; y: number; z: number }
type Propkeys = 'x'|'y'|'z'
type Type2 = { [Key in PropKeys]: number }
还可以根据对象类型来创建
type Props = { a: number; b: string; c: boolean }
//所有类型变成number
type Type3 = { [key in keyof Props]: number }
索引查询类型
- 获取属性的类型
type Props = { a: number; b: string; c: boolean }
type TypeA = Props['a']
- 同时查询多个索引类型
type Props = { a: number; b: string; c: boolean }
//number | string
type TypeA = Props['a'|'b']
//number | string | boolean
type TypeA = Props[keyof Props]
类型声明文件
用来为已存在的JS库提供类型信息
- .t文件:
- 既包含类型信息又可执行代码
- 可以被编译为.js文件
- 用途:编写程序代码的地方
- .d.ts文件
- 只包含类型信息的类型声明文件
- 不会生成.js文件,仅用于提供类型信息
- 用途:为JS提供类型信息
内置声明文件:Ctrl+鼠标左键来查看内置类型声明文件
- 创建自己的类型声明文件1
//index.d.ts文件中
type Props = { x: number; y: number }
export { Props }
//.ts文件中
import {Props} from './index'
Let p2: Props = {
x: 10,
y: 22
}
- 创建自己的类型声明文件2
//在js中
Let count = 10
Let songName = '痴心'
let position = {
x: 0,
y: 0
}
function add(x,y) {
return x + y
}
function changeDirection(direction) {
console.log(direction)
}
const fomartPoint = point => {
console.log('当前坐标',point)
}
export { count,songName,position,}
//在.d.ts中
declare Let count: number
declare Let songName: string
interface Point {
x: number
y: number
}
declare Let position: Point
declare function add(x: number, y: number): number
declare function changeDirection(
direction: 'up'|'down'|'left'|'right'
): void
type FomartPoint = (point: Point) => void
declare const fomartPoint: FomartPoint
export { count, songName,position add,}