【TypeScript】Re01
参考视频:
https://www.bilibili.com/video/BV14Z4y1u7pi
JS已有类型:
基础类型 number / string / boolean / null / undefined / symbol
对象类型 object (数组,对象, 函数)
TS类型:
1、联合类型
2、类型别名
3、接口
4、元组
5、字面量类型
6、枚举
7、void
8、any
函数类型:
function add1(n1: number, n2: number): number {
return num1 + num2
}
// 箭头函数可以在注解方法参数时指定参数类型和返回类型
const add2 = (n1: number, n2: number): number => n1 + n2
// 或者第二种,直接对变量注解方法类型
const add3: (n1: number, n2: number) => number
= (n1, n2) => n1 + n2 // 函数无返回类型时注解为 void
function greet(name: string): void {
console.log('hello', name)
}
// 或者这样写
const greet: (name: string) => void = name => console.log('hello', name) // 可选参数, 一般放在必填参数的后面使用
function mySlice(start?: number, end?: number): void {
console.log('起始索引', start, '结束索引', end)
}
对象类型:
let person: {
name: string,
age: number,
sayHi(): void,
greet(name: string): void
} = {
name: 'jack',
age: 19,
sayHi(){},
greet(){}
}
// 如果是注解成一行编写
let person: { name: string; age: number; sayHi(): void; greet(name: string): void; } // 可选属性
function myAxios(config: { url: string; method?: string }) {}
myAxios(url: 'asdasdasd')
接口类型:
// 用于复用对象类型
interface IPerson = {
name: string
age: number
sayHi(): void
} let person: IPerson = {
name: 'jack',
age: 19,
sayHi() {}
}
接口和类型别名的区别:
接口只能为对象指定类型
类型别名:包括对象类型,支持任意类型 interface IPerson = {
name: string
age: number
sayHi(): void
}
type IPerson = {
name: string
age: number
sayHi(): void
}
type NumStr = number | string
接口继承:
// 接口继承,用于多余属性复用
interface Point2D { x: number; y: number }
interface Point3D { x: number; y: number; z: number } // x轴和y轴都冗余了,使用extends实现
interface Point2D { x: number; y: number }
interface Point3D extends Point2D { z: number }
元组类型:
经纬度,长度固定2个 // 数组长度可以多个
let position: number[] = [39.5427, 116.1327] // 元组固定两个元素
let point: [number, number] = [39.5427, 116.1327]
类型断言:
// 强制断言一个类型
const aLink = document.getElementById('link') as HTMLAnchorElement // 语法2
const aLink = <HTMLAnchorElement>document.getElementById('link')
字面量类型:
// let是变量 值可以是任意字符, ts推测类型是string
let str1 = 'Hello TS' // const是常量 值不能变化只能是hello ts 所以类型即为 hello ts
const str2 = 'Hello TS' // 显示声明
let str1: string = 'Hello TS'
const str2: 'Hello TS' = 'Hello TS' // 当变量定义常量值类型时,等效const
let age: 18 = 18 // 结合 联合类型处理,只能在已列出的几种常量中选择
function directionChangeTo(direction: 'up' | 'down' | 'left' | 'right') {
console.log(direction)
}
枚举类型:
代替联合类型,更具体的表示入参选项
enum Direction {
Up,
Down,
Left,
Right
} // 方法参数声明
function changeDirection(direction: Direction): void {
console.log(direction)
}
// 箭头函数声明
const changeDirection2: (direction: Direction) => void = direction => {
console.log(direction)
}
// 调用
changeDirection(Direction.Up) // 枚举是存在默认值的(自增下标),支持自定义值
enum Direction { Up = 2, Down = 4, Left = 8, Right = 16 } // 如果是字符串枚举,则没有自增迭代值了
enum Direction { Up = 'Up', Down = 'Down', Left = 'Left', Right = 'Right' }
any类型:
// 失去TS类型保护, 不再编译警告
let obj: any = { x: 0 }
obj.bar = 100
obj()
const n: number = obj
typeof 操作符
1、在类型上下文中引用变量或者属性的类型
根据已有变量获得该变量的类型描述
2、只能用来查询变量或属性的类型,无法查询其它形式的类型 // 不使用typeof
let p = { x: 1, y: 2}
function formatPoint(point: { x: number; y: number }) {}
formatPoint(p) // 使用typeof
function formatPoint(point: typeof p) {}
高级类型
- Class类
- 类型兼容性
- 交叉类型
- 泛型 + Keyof
- 索引签名 + 索引查询
- 映射类型
Class类-1 创建类和属性
// js 语法
class Person {}
const p = new Person() // ts 创建类和属性
class Person {
age: number
gender = '男' // 构造器默认为类的类型
constructor(age: number, gender: string) {
this.age = age
this.gender = gender
}
}
const p = new Person(18, '男')
Class类-2 实例方法
// 实例方法
class Point {
x = 1
y = 2 scale(n: number) {
this.x *= n
this.y *= n
}
}
const p = new Point()
p.scale(10)
Class类-3 类的继承
// class的继承
class Animal {
move() { console.log('Moving along') }
} class Dog extends Animal {
name = '二哈'
bark() { console.log('汪') }
}
const dog = new Dog()
dog.move()
dog.bark()
console.log('旺旺')
Class类-4 接口的实现
// class 的实现
interface Singable {
sing(): void
name: string
} class Person implements Singable {
name = 'jack'
sing() {
console.log('13766~')
}
} const jack = new Person()
jack.name
jack.sing()
Class类-5 访问修饰符
// 访问修饰符 public -> protected -> private
// 默认可见性 public,即省略不写
class Animal {
public move() {
console.log('')
}
}
// protected 仅对所在类和子类中可见(实例对象不可见)
class Animal {
protected move() {
console.log('Moving along')
}
}
class Dog extends Animal {
bark() {
console.log('汪')
this.move()
}
}
// private 只在当前类中可见(实例对象及子类不可见)
// 编写规范, private 方法名称 使用双下划线修饰左右两边
class Animal {
private __move__() {
console.log('Moving along')
}
walk() {
this.__move__()
}
}
// readonly 只读修饰符,只读防止在构造函数之外对函数赋值,只能修饰属性,不能修饰方法
// 接口或者{}表示的对象类型也支持readonly修饰
class Person {
readonly age: number = 18 // 提供一个默认值
constructor(age: number) {
this.age = age
}
}
类型兼容问题:
// 类型兼容问题
类型系统:Structural Type System (结构化类型系统), Nominal Type System (标明类型系统)
TS用STS系统 Duck Typing 类型检查关注值本身的类型,如果对象具有相同形状,则类型相同 // Duck Typing 如果它走路像鸭子,声音像鸭子,样子也像鸭子,那他就是鸭子
// NTS标明类型系统 例如Java 即使字段属性一样,但是不是同类型,就不兼容(以接口方式进行兼容) // 样例
class Point { x: number; y: number }
class Point2D { x: number; y: number } const p: Point = new Point2D() // Class以多兼容少
class Point { x: number; y: number }
class Point3D { x: number; y: number; z: number }
const p: Point = new Point3D() // interface以多兼容少,同属性兼容
interface Point { x: number; y: number }
interface Point2D { x: number; y: number }
let p1: Point
let p2: Point2D = p1 interface Point3D { x: number; y: number; z: number }
let p3: Point3D
p2 = p3 // 如果class 和 interface 同属性,方法,一样兼容的
函数类型兼容:
// 函数兼容
// 参数个数,参数类型,返回值类型 // 1、参数个数兼容, 参数多的函数兼容参数少的函数
type Fun1 = (a: number) => void
type Fun2 = (a: number, b: number) => void
let fun1 = Fun1
let fun2 = Fun2 = fun1 // 2、方法样例, forEach自动推导函数参数个数和类型
const arr = [1, 2, 3]
arr.forEach(() => {})
arr.forEach(item => {}) 3、参数类型兼容
interface Point { 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
f3 = f2 4、返回值类型同理
type F7 = () => { name: string }
type F8 = () => { name: string; age: number }
let f7: F7
let f8: F8
f7 = f8
接口交叉类型:
类型组合在一起实现
// 交叉类型 交叉符& 联合两个接口的属性,成一个新的类型
interface Person { name: string }
interface Contact { phone: string }
type PersonContact = Person & Contact
let pc: PersonContact = {
name: 'cloud9',
phone: '13755684304'
}
交叉类型和继承的区别?
// 交叉类型 和 继承 的区别?
1、都是为了对象类型的组合
2、处理对象类型冲突的属性方式不一样
- extends 会触发冲突警告
- & 会将冲突类型进行联合 interface A { fn: (val: number) => string }
interface B extends A { fn: (val: string) => string } // 语法警告 fn类型冲突 interface A { fn: (val: number) => string }
interface B { fn: (val: string) => string }
type C = A & B
// fn: (val: string | number) => string 参数类型将被联合起来
TS泛型:
TS 泛型处理:
function genericType<Type>(val: Type): Type {
return val
}
const num = genericType<number>(10)
const str = genericType<string>('2334')
const bool = genericType<boolean>(true) 泛型约束:
// 1、可以约束泛型为具体类型数组 Array<Type> ?
function genericTypeConstraint<Type>(val: Type[]): Type[] {
return val
} // 2、可以指定为某一个类型的子类型
interface ILength { length: number } // 该泛型必须要拥有ILength具备的属性
function genericTypeConstraint<Type extends ILength>(val: Type): Type {
console.log(val.length)
return val
} genericTypeConstraint([1, 2, 3])
genericTypeConstraint('123')
genericTypeConstraint({ length: 10, name: 'cloud9' }) // 3、支持添加多个泛型,泛型之间可以进行约束设置
function getProp<Type, Field extends keyof Type>(obj: Type, key: Field) {
return obj[key]
}
let person = { name: 'jack', age: 18 }
getProp(person, 'name')
getProp(18, 'toFixed')
getProp('abc', 'split')
getProp([1, 2, 3], 'length')
getProp([1, 2, 3], 1) // 4、接口与泛型的组合
interface IdFunc<Type> {
id: (val: Type) => Type
ids: () => Type[]
}
// 使用泛型时,需要指定泛型的具体类型
let obj: IdFunc<number> = {
id(val) { return val },
ids() { return [1, 3, 5] }
} // 5、泛型工具类
Partial<Type> 创建一个Partial类型,该类型泛型的类型属性可选
Readonly<Type> 创建一个ReadOnly类型,该类型泛型的类型属性只读
Pick<Type, Keys> 创建一个Pick类型, 根据Keys类型返回一个新的对象
Record<Keys, Type> 创建一个Record类型,根据Keys和Type返回对象
索引类型:
// 索引类型签名:
interface AnyObject {
// key表示键名占位符,可以命名其他名称
// 约束键类型为string, 值类型为number
[key: string]: number
} let obj: AnyObject = {
a: 1,
b: 2
} interface MyArray<T> {
[idx: number]: T
} let arr: MyArray<number> = [1, 3, 5]
arr[0] // 映射类型, 只能再type中使用
type PropKeys = 'x' | 'y' | 'z'
type Type1 = { x: number, y: number, z: number }
type Type2 = { [Key in PropKeys]: number } // 除了联合类型映射,还支持类型键集合映射
type Type3 = { x: number, y: number, z: number }
type Type4 = { [Key in keyof Type3]: number } // 索引查询
type Type5 = { x: number, y: string, z: boolean }
type TypeX = Type5['x'] // number, 被查询的键名必须在该类型中存在,否则报错 // 联合查询 查询指定类型中具体某个索引的类型,或者是索引类型的联合
type Type6 = { x: number, y: string, z: boolean }
type TypeXwithY = Type6['x' | 'y'] // number | string
type Type6Union = Type6[keyof Type6] // number | string | boolean
类型声明文件:
TS两种文件类型:[***.ts | ****.d.ts] 两种文件的区别?
- ts 文件
1、包含类型信息和执行逻辑
2、可以编译为.js文件,然后执行代码
- d.ts 文件 (d代表declare)
1、只包含类型信息的类型声明文件
2、不会生成js文件,仅提供类型信息 d 类似Java的接口
定义 变量、对象类型、方法声明 用法:
- - - - - index.d.ts - - - - -
type Props = {
x: number
y: number
} export { Props } // 或者直接 export
export type Props = {
x: number
y: number
} - - - - - index.ts - - - - -
import { Props } from './index'
ts.config.js 的配置声明:
https://www.bilibili.com/video/BV14Z4y1u7pi?p=79
【TypeScript】Re01的更多相关文章
- 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。
[TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...
- 【TypeScript】TypeScript 学习 5——方法
在 JavaScript 中,有两种方式定义方法. 1.命名的方法 function add(x,y){ return x+y; } 2.匿名方法 var myAdd = function(x,y) ...
- 【TypeScript】TypeScript 学习 4——模块
前端数据验证在改善用户体验上有很大作用,在学了之前的知识的时候,我们很可能会写出以下代码: interface StringValidator { isAcceptable(s: string): b ...
- 【TypeScript】TypeScript 学习 3——类
在 EcmaScript 6 中,我们将会拥有原生的类,而不是像现在通过原型链来实现.使用 TypeScript 我们能提前体验这一特性. 首先来看看一个简单的例子: class Greeter { ...
- 【TypeScript】TypeScript 学习 2——接口
在 TypeScript 中,接口是用作约束作用的,在编译成 JavaScript 的时候,所有的接口都会被擦除掉,因为 JavaScript 中并没有接口这一概念. 先看看一个简单的例子: func ...
- 【TypeScript】TypeScript 学习 1——基本类型
TypeScript 是 JavaScript 的超集,TypeScript 经过编译之后都会生成 JavaScript 代码.TypeScript 最大的特点就是类型化,因此才叫做 TypeScri ...
- 【TypeScript】学习笔记 把一些需要记的记录一下
安装typescript: npm install -g typescript 启动typesctipt自动编译: tsc 文件名.ts --watch 函数参数默认值: 1.有默认值参数的,声明在最 ...
- 【Spring-Security】Re01 入门上手
一.所需的组件 SpringBoot项目需要的POM依赖: <dependency> <groupId>org.springframework.boot</groupId ...
- 【vue3-element-admin 】基于 Vue3 + Vite4 + TypeScript + Element-Plus 从0到1搭建后台管理系统(前后端开源@有来开源组织)
vue3-element-admin 是基于 vue-element-admin 升级的 Vue3 + Element Plus 版本的后台管理前端解决方案,技术栈为 Vue3 + Vite4 + T ...
- 【译】JavaScript 开发者年度调查报告
截至目前有超过了 5000 人参与了(该次调查),准确的说是 5350 人.我迫不及待的想要和大家分享一下这次调查的细节.在分享之前我想要感谢参与调查的每一个人.这是 JavaScript 社区一个伟 ...
随机推荐
- uniapp colorui的使用
1.首先我们在Hbuilder x中新建一个uniapp的项目,如下图所示,选择 colorUI项目 2.copy 项目文件夹下的colorUI文件夹到你的项目中去,如下图所示 3.打开根目录下的Ap ...
- WPS相关技巧
1 标题自动编号 首先,新建一个空白word,打开.点击默认的标题样式,可以看到并不会自动编号. 接下来,就设置如何自动编号.首先选择"编号". 然后,选择"多级编号&q ...
- [经验分享] VPS安装爱快
前言:本人是作VPN服务端用,配合域名分流,蛮好用.参考1.送一个阿里云腾讯云安装爱快3.X的文档https://bbs.ikuai8.com/thread-97314-1-1.htmlVPS存在的问 ...
- vue过滤器 - filters
在数据被渲染之前,可以对其进行进一步处理,比如将字符截取或者将小写统一转换为大写等等,过滤器本身就是一个方法. 过滤器可以定义全局或局部 # 全局 // 回调函数中的参数1永久是绑定的数据 Vue.f ...
- LeetCode 451. Sort Characters By Frequency 根据字符出现频率排序 (C++/Java)
题目: Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Inp ...
- kettle从入门到精通 第三十五课 kettle 变量
1.设置变量 a.可以通过转换中的"设置变量"步骤进行设置. b.手动通过kettle.properties文件或通过"编辑"菜单中的"设置环境变量& ...
- The solution of ABC144F
都不知道什么时候做的题了 problem & blog 一开始很容易想到枚举断边然后 DP 算代价. 于是很容易想到 DP 状态定义:设 \(dp_u\) 为从 \(u\) 出发到 \(n\) ...
- mysql数据库慢SQL优化
mysql数据库慢SQL优化优化来源: 阿里云 云数据库RDS 慢sql 或者CAT监控系统中的Transaction SQL or URL根据平均时间反馈来排查,决定是否增加索引,或者调整业务逻辑代 ...
- linux挂载的ntfs格式硬盘无法使用回收站
linux挂载的ntfs格式硬盘无法使用回收站 解决办法: 新建回收站文件, 文件名为Trash-XXX . 比如Trash-1000 这里的1000就是你的$UID. sudo mkdir /.Tr ...
- C#/.NET/.NET Core优秀项目和框架2024年6月简报
前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍.功能特点.使用方式以及部分功能截图 ...