ts
优势
静态类型检查,提前发现错误
良好的代码提示
需要编译才可以使用
准备工作
-
需要node环境
- npm下载npm i typescript
- 编译单个文件 tsc 文件名 -w (-w自动编译)
- 编译整个文件 tsc (需要tsconfig.json)
-
ts声明变量时会自动判断类型
数据类型
-
简单类型
number、string、boolean、null、undefined、symbol
-
复杂类型
object(对象、数组、函数)
-
新增类型
联合类型 | 类型别名 type 接口interface 字面量类型 相当于常量 泛型 枚举 void 无返回值 any 任意类型,会影响别人 unknown 未知类型,只影响自己 元祖 [string,number] 固定长度,指定类型的数组
普通值
let num:number = 123
let str:string = 'abc'
let bool:boolean = true
对象
let obj:{
name:string,必须存在属性name
age?:number,可选属性age
[propName:string]:any],其他所有字符串属性都是可选的-propName 可以是任意名字
}
数组
let arr:number[] = [1,2,3]
let arr:(number|string)[] = ['a',1,2,3]
let arr:Array<number|string>=['a',1,2,3]
函数
// 普通函数
function fn1(n1: number, n2: number): number {
return n1 + n2
}
// 箭头函数
let fn2: (n1?: number, n2?: number) => number
fn2 = (n1, n2) => n1 + n2
// 或者
type fn3 = (n1: number, n2: number) => number
const fn3: fn = (n1, n2) => n1 + n2
// 箭头函数(整体注释)
const fn4 : (n1:number,n2:number) => number = (n1,n2) => n1 + n2
接口interface
接口是用于定义一个标准,都是抽象的属性和方法(也不完全是),类似于class类
可以重复声明,属性和方法会叠加、可以继承、可以嵌套
// 普通
interface Father {
name: string
age?: number
}
interface Father {
sex: boolean
}
const f: Father = {
name: 'yj',
sex:true
}
// 继承
interface Son extends Father {
kaoshi:number
}
const s:Son = {
name:'zz',
kaoshi:99
}
// 嵌套
interface Sun {
eye:number,
data:F
}
const sun: Sun = {
eye: 2,
data: {
name: 'yy',
age:99
}
}
接口实现
// 接口定义对象的结构,包含属性和方法声明
interface Person {
name: string; // 必需属性
age?: number; // 可选属性
greet(): void; // 抽象方法
sayHello(): string; // 抽象方法
walk?(): void; // 可选方法
}
// 实现接口
class Student implements Person {
name: string;
age?: number;
constructor(name: string, age?: number) {
this.name = name;
this.age = age;
}
greet() {
console.log("Hello, I'm " + this.name);
}
sayHello() {
return "Hello";
}
}
// 创建实例
const student = new Student("Alice", 25);
student.greet(); // 输出:Hello, I'm Alice
console.log(student.sayHello()); // 输出:Hello
类型type
不可以重复声明
type Father = {
name: string
age?: number
}
const f: Father = {
name: 'yj',
age: 19
}
type Son = Father & {
sex: boolean
}
const s: Son = {
name: 'zz',
age: 29,
sex: true
}
抽象类、抽象方法abstract
abstract class Person {
abstract sayHei():void // 这个抽象类,只能被继承,不能被实例化
}
let p = new Person() // 不允许,只能被继承
class Man extends Person{
sayHei(){} // 必须重写父类的方法,否则ts报错
} // 允许,可以被继承
修饰符 public 、private 、protected
class P {
private _name: string
public _age: number
protected _sex: number
constructor(_name:string,_age:number) {
this._name = _name
this._age = _age
}
go1(){
this.
}
}
let yj = new P('yj',99)
yj._name = 'zd2' // ts报错,提示,私有的_name属性无法控制
yj._age = 999 // ts不报错,公共属性可以修改
console.log(yj);
class P {
private name: string
public age: number
protected sex: number
constructor(name: string, age: number, sex: number) {
this.name = name
this.age = age
this.sex = sex
}
changeSex() {
this.sex = 999
}
}
class PPPP extends P {
changeSex() {
this.sex = 999
}
}
let yj = new P('yj',9,0)
let yjj = new PPPP('yj',9,0)
yj.name = 'yjj' // ts报错,提示,属性name是私有的,只能在当前类中修改
yj.age = 99
yj.sex = 1 // ts报错,提示,属性sex受到保护,只能在当前类和子类中修改
yj.changeSex()
yjj.changeSex()
断言(欺骗ts)
const link = document.qs('link') as HTMLAnchorElement
link.可访问链接元素身上的方法
泛型
// 对象和泛型
interface User {
token: string
id: number
}
interface List {
arr1: number[]
arr2: Array<number>
}
interface ResData<T> {
code: number
message: string
data: T
}
const userRes: ResData<User> = {
code: 100,
message: 'ok',
data: {
token: 'asd',
id: 1
}
}
const listRes: ResData<List> = {
code: 100,
message: 'ok',
data: {
arr1: [1],
arr2: [1]
}
}
// type和interface基本相同
// 函数和泛型
function Myjoin<T>(len: number, value: T): void {
const arr = []
for (let i = 0; i < len; i++) {
arr[i] = value
}
console.log(arr)
}
const res = Myjoin<string>(5, 'c')
const res2 = Myjoin<number>(3, 4)
pick挑选属性
// Pick 可以从一个对象类型中 取出某些属性
type Person = {
name: string
age: number
sex: 0|1
}
type PickPerson = Pick<Person, 'age'|'sex'>
// PickPerson === { age: string, sex: 0|1 }
###omit去除属性
// Omit 可以从一个对象类型中 排出某些属性
type Person = {
name: string
age: number
sex: 0|1
}
type OmitPerson = Omit<Person, 'age'|'sex'>
// OmitPerson === { name: string }
Partial属性转为可选
type Person = {
name:string
age?:number
sex?:0|1
}
type PartialPerson = Partial<Person>
// PartialPerson
{name? age? sex?}
Required属性转为必选
type Person = {
name:string
age?:number
sex?:0|1
}
type RequiredPerson = Required<Person>
// RequiredPerson
{name age sex}
keyof 提取所有属性
interface Person {
name: string;
age: number;
id: number;
}
// Person 所有键的联合类型
type Keys = keyof Person; // 等效于 "name" | "age" | "id"
// 相当于
interface Keys {
name: string;
age: number;
id: number;
}
enum 枚举
// 不需要直接写入常量,比如1234具体值(没有语义),而是用fx.单词还获取数字(有语义)
// 枚举具有默认值
enum fx {
left = 1,
right = 2,
top = 3,
bottom = 4
}
console.log(fx.right)
告诉ts是全局变量
/* global 变量名 */
后续的该变量名就不会提示引入错误,被TS认为是已经被全局引入过
tsconfig.json
ts的配置文件,直接放在根目录
{
"include":["./src/**/*"], // 需要编译的路径
"exclude":["./dist/**/*"], // 不需要编译的路径
"extends":"./config/base", //继承其他的规则
"files":["core.ts","sys.ts"], // 指定编译文件
"compilerOptions": {
"target": "ES6",//编译指定es版本 ts=>js
"module": "ESNext",//编译指定模式es6、commonjs
// "lib": [],
"outDir": "dist2", //编译保存的文件夹,
// "outFile": "./dist/app.js", //编译合并保存文件
"allowJs": true, //是否编译js文件(文件夹中除了ts之外可能还存在js文件,是否一起编译了)
"checkJs": true, //是否检查js代码符合规范
"removeComments": true, //是否移出注释
"noEmit": false ,// 是否生成编译后的文件
"noEmitOnError": true, //有错误时,不编译生成文件
"strict": true,//所有严格模式的总开关,开启后,所有相关属性全部打开和关闭(优先级没有单独写高)
"alwaysStrict": false,// 开启严格模式 use strict
"noImplicitAny": true,// 不允许出现默认any类型
"noImplicitThis": true, // 不允许出现不明确类型的this
"strictNullChecks": true // 严格的检验是否为空,万一什么东西没获取到
}
}