Ts
-
什么是Ts?
- 全称: teypscript , 它是js的超集,它提供了js没有类型系统,我们可以对数据进行强类型定义,
-
开发者
- 微软
-
开源项目
-
ts如何使用
- 全局安装typescript -> 目的是为了有 tsc 命令,这个tsc是用来转换ts文件为js文件的
-
文件转换
- Ts -> Js
- es7 -> es5
-
Ts在代码的编译阶段就能够报错
- 即使报错我们也可以转换文件
-
类型推论
- 我们可以根据值来确定变量的数据类型
类型:
原始数据类型:布尔值、数值、字符串、null、undefined、symbol、void、any
内置对象类型:Boolean, Error, Array, Date, Math, RegExp
Document,HTMLElement,Event,NodeList … MouseEvent
自定义类型: 类、接口、
类型定义:
数值、字符串
布尔值 let isDone: boolean = false;
NewBoolean: boolean = new Boolean(1);返回对象
null undefined 同理
空值 let unusable: void = undefined
function alertName(): void{}
注意:undefined 和 null 是所有类型的子类型,可以赋值给 number 类型的变量,而 void 类型的变量不能赋值给 number 类型的变量
任意值:any 允许被赋值为任意类型,任何操作都返回任意值,是任意类型的父类型
类型推论
没有明确的指定类型,依照值推断出一个类型。
联合类型
取值可以为多种类型中的一种,没列出的不可以
let myFavoriteNumber: string | number;
对象类型:依赖接口|类 来描述,不给类型可以推论
接口定义:后续接口会单说
interface Person {
name: string;
age: number;
}
let p:Person={name:'xx',age:11}
注意:定义的变量比接口少了一些属性是不允许
可选属性: age?: number;
任意属性: [propName: string]: any; 任意值
注意:必填属性和可选属性都必须是任意属性的子属性
例如:[propName: string]: string 其他属性要是string子属性
只读属性: readonly id: number; 只能创建的时候被赋值
数组的类型:
变量:类型[]:
let arr: number[] = [1, 1, 2, 3, 5];
let arr: any[] = [1, 1, 2, 3, 5];
Array<elemType>: 泛型 后面会单说
let arr: Array<number> = [1, 1, 2, 3, 5];
函数的类型:
一个函数有输入和输出,进行约束,需要把输入和输出都考虑到
function sum(x: number, y: number): number {}
注意:输入多余的(或者少于要求的)参数,是不被允许的
函数表达式:let mySum = function (x: number, y: number): number {}
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {}
变量:输入类型=>输出类型=function(参数){}
可选参数: function buildName(a: string, b?: string) {}
注意:可选参数在后
参数默认值: lastName: string = 'Liu' 默认值在后
接口中函数的定义:
interface SearchFunc {
(a: string, b: number): boolean;
}
let c: SearchFunc=function() {return true}
c('qq',11)
声明文件
ts 使用第三方库时,我们需要引用它的声明文件
ts 并不知道 $ 或 jQuery 是什么东西
declare 关键字来定义它的类型,帮助 TypeScript 判断我们传入的参数类型对不对
declare var jQuery: (string) => any;
jQuery('#div1');
类型声明放到一个单独的文件中,这就是声明文件jQuery.d.ts
declare var jQuery: (string) => any;
用到的文件的开头用「三斜线指令」表示引用了声明文件
/// <reference path="./jQuery.d.ts" />
安装第三方声明文件
npm install @types/jquery --save-dev
引入第三方方声明文件
import * as jQuery from 'jquery';
import * as $ from 'jquery';
类:
类(Class):定义了一件事物的抽象特点,包含它的属性和方法
对象(Object):类的实例,通过 new 生成
面向对象(OOP)的三大特性:封装、继承、多态
封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
实例属性: 定义在类内部 name = 'Jack'; | public xx:string 定义在构造器内部 | get|set 属性(){}
继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
es6: 使用 extends 关键字实现继承,子类中使用 super 关键字来调用父类的构造函数和方法
存取器(getter & setter):用以改变属性的读取和赋值行为
es6: 使用 get 属性(){return this._属性} 和 set 属性(val){this._属性=val} 可以改变属性的赋值和读取行为
静态方法 | 类方法: static 方法名(){} 类名.方法()
静态属性 | 类属性: static 定义在类内部 name = 'Jack'; ts实现了但转换到js暂不支持 调用:类名.方法()
访问修饰符(Modifiers ts实现):修饰符是一些关键字,用于限定成员或类型的性质。比如 public 表示公有属性或方法
public:修饰的属性或方法是公有的,默认所有的属性和方法都是 public 的
private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
protected 修饰的属性或方法是私有的+子类中允许访问
类的类型 公司里面: 董事长位置: 继承制
public name: string;
constructor(name: string)
sayHi(): void{}
p1: Person = new Person
接口:
可以用于对象的形状描述,函数的类型描述,类的行为进行抽象
思想:实现(implements)不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现
门是一个类,防盗门是门的子类。防盗门有一个报警器的功能,给防盗门添加一个报警方法。车类,也有报警器的功能,就可以考虑把报警器提取出来,作为一个接口,防盗门和车都去实现它
interface Action{ 定义接口
readonly id: number;//只读属性
name:string;
age?:number;可选
[propName: string]: any;//任意属性
eat?():string 可选方法的返回值
}
类实现接口:class 类 implements 接口{}
类实现多个接口:class 类 implements 接口1,接口2{}
泛型:
定义"变量" 时不确定类型,希望在使用时再来确定类型
在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性
function 函数<T,U>(length: number, value: T,arg:U): Array<T|U> {}
函数名后添加了 <T>,指代任意输入的类型 value: T 接收任何输入类型 Array<T>输出数组泛形
函数<string,number>(参数) 使用的时候再指定类型
/*
- ts就是js
- ts多了类型系统
- 使用Ts
- 将Ts转化成js
- ? 如何转换? tsc
*/
const sum = ( a, b ) => {
return a + b
}
console.log( sum( 10,20 ) )
const num = 100 // num是数值类型 当我定义变量时,ts会根据我们值来给我们变量确定类型,并且一旦确定不可变
// num = ‘aaa’
let str = ‘safdsa’
str = 1000
/*
Ts类型
1. 原始数据类型
- number
- string
- null
- undefined
- symbol
2. 内置对象类型
- Array
- Object
- Document,HTMLElement,Event,NodeLis
3. 自定义类型
- 类 class
- 接口 interface
*/
/*
- 数组定义类型
-
- 格式
- const/let 变量名:数据类型[] = 变量值
- const/let 变量名:Array< 数据类型 > = 变量值
*/
-
/* js写法 */
const arr = [1,2,3]
const newarr = new Array( 1,2,3 )
/* ts写法 */
const arr1: number[] = [1,2,3] // 定义一个元素为数值类型的数组
// arr1.push(‘a’) 我们发现加不进去
const arr2: string[] = [‘a’,‘b’] // 定义了一个元素为字符类型的数组
// arr2.push( 3 )
// ? 如果既有数值类型又有字符类型如何定义
const arr3: (number|string)[] = [ 1,2,‘a’] // 定义了一个number联合string类型的数组
const arr4: Array = new Array( 1,2,3 )
const arr5: Array = new Array( ‘a’,‘b’,‘c’ )
/*
- 原始数据类型
- number
- string
- null
- undefined
- symbol
- 定义格式
var/const/let 变量名:数据类型 = 变量值
*/
/* js来定义类型 */
const n = 100
const s = ‘a’
const nul = null
const und = undefined
/* ts来定义类型 */
const n1:number = 100
const s1:string = ‘b’
const nul1:null = null
const und1:undefined = undefined
const sym: Symbol = Symbol( 1 )
/*
内置对象类型
*/
const bol: Boolean = new Boolean( true ) // 定义一个类型为Boolean的布尔值
const html: HTMLElement = document.querySelector(‘html’) // 为html节点定义了一个HTMLElment数据类型
const div: HTMLElement = document.querySelector(‘div’)
const date:Date = new Date()// 给变量date定义了一个Date类型
/*
- 函数定义类型
- 形式参数 和 函数返回值
*/
- 形式参数 和 函数返回值
/* js写法 */
function fn ( a, b ) { return a + b } // function 关键字定义一个函数
const fn1 = function ( a,b ) { return a + b } // 通过字面量形式定义一个函数
const fn2 = (a,b) => a + b
/* Ts写法 */
function fn3( a:number,b:number):number {
return a + b
}
const fn4 = function ( a:number,b:number ):number { return a + b }
const fn5 = function ( a:string,b:string ):void{} // void表示数据类型为空
const fn6 = (a:string,b:number ):number => 100
/* ts对函数的特别写法 - 推荐 */
// const fn7:输入类型[参数]=> 输出类型【 返回值】 = 函数体
const fn7:( a:number,b:number) => number = function ( a,b ) { return a + b }
const fn8:( a:string,b:string ) => string = ( a,b ) => a + b
/* ts还提供了自定义接口来定义函数 - 项目实战使用 */
const fn9:Fn = (n,m) => n + m
interface Fn{ // 通过interface 关键字定义了一个Fn接口
// 输入类型:输出类型
(n:number,m:number):number
}
/*
- ts是如何对对象进行定义数据类型
- 使用接口来定义对象数据类型
*/
- 使用接口来定义对象数据类型
var obj:Obj = {
id: 1,
name: ‘Gabriel yan’,
sex: ‘man’,
age: 18,
jineng ( n,m ) {
return n + m
},
classRoom: 1907,
cat: ‘猫’
}
interface Obj{
readonly id: number, // 只读属性,只能展示,不能修改
name: string, // 必传属性
sex: string,// 必传属性
age: number,// 必传属性
jineng: any, //any表示任意类型,
classRoom: number,
cat?: string, // 可传属性,也就是说这个属性将来在obj对象可以写也可以不写
[ propName: string ]: any // 任意属性 //表示将来添加的属性的数据类型为任意类型
}
// obj.id = 2
// obj.title = “dsafa”
// obj.head = ‘h5’
/*
js定义一个类
*/
class Hello{
// 实例成员
// 实例属性
// 实例方法
// 类成员【 静态成员 】
// 静态属性
// 静态方法
}
// 实例是什么? 实例就是通过new 类得到的结果
// 静态成员是什么? 静态成员就是类身上的属性和方法
const hello = new Hello()
9./*
js定义一个类
*/
class People{
// 实例成员
// 实例属性
a:number = 100
// 实例方法
b = ( a:number,b:number ):number => a + b
// 类成员【 静态成员 】
// 静态属性
static c:string = ‘dsfs’
// 静态方法
static d = ( a:string,b:string): string => a + b
}
const people = new People()
people.a
people.b
People.c
People.d
class Person implements PersonInterFace{ // 使用接口来实现类
a = 100
b = ‘Hello Ts’
}
interface PersonInterFace{
a: number,
b: string
}