Ts
基本类型
1.布尔类型 boolean
let flag: boolean = false
2.数字类型 number
let a: number = 123
3.字符串类型 string
let str: string = 'this is string'
4.数组类型 array 定义数组两种方式
(1) 第一种
let arr: number[] = [1,2,3,4]接收一个数组 数组里面的元素是对象类型 (实际开发)let arr1: {id:string,name:string}[]
(2) 第二种(泛型)
let arr: Array<number> = [1,2,3,4]
5.元组类型 tuple 属于数组得一种 可以定义数组里每一个元素得类型
let arr: [string,number,boolean] = ['字符串',123,false]
6.枚举类型 enum
定义得格式:
enum 枚举名 { 标识符[=整型常数], 标识符[=整型常数], ... 标识符[=整型常数], };
适用于参数映射表示 标识状态码
0 未支付 1 支付 2 交易成功
enum Flag {success=1,error=-1} let f: Flag=Flag.success
定义的枚举值是可以赋值默认值得 如果没有给值 默认从下标值开始 如果赋值 这个值就是洗一个值得起始值
eg:
enum Color {red,blue=5,orange} let c: Color = Color.red let o: Color = Color.orange打印c是0 o是6
7.任意类型 any
用处 给Dom节点添加样式 获取dom节点时使用
let oBox: any = document.getElementById('html)
8.空类型 null 和 undefined(其他类型(never类型)的子类型)
报错写法飘红
var num: number; console.log(num) 输出undefined 这个会飘红
正确写法
var num: undefined; console.log(num) 输出undefined 这个不会飘红
日常写法:存在或者不存在的写法 变量定义但没有被赋值
var num: number | undefined | null
9.void类型表示方法没有返回任何类型 一般是定义一个方法的时候没有返回值
function run(): void{ console.log('无任何返回') }
10.never类型 是其他类型(null和undefined)的子类型代表从不会出现的值
声明never的变量只能被never类型赋值 eg:
var a: undefined; a=undefined 不会报错 a=123 报错var b: null; b=null 不会报错 b=123 报错一般用于抛出异常错误a:never a=(()=>{ throw new Error('错误') })()
Ts中函数的定义
第一种:入参和返回值都有定义类型
1.配置可选参数
function run (name:string,age?:number):string{
return '字符串'
}
age可传可不传 ?配置可选参数
配置可选参数 可选的必须要放置参数的最后面!!!!
2.配置默认参数
function run (name:string,age:number=20):string{
return '字符串'
}
调用时仍然可以传age参数,这个时候生效值是传入的值
- 配置剩余参数
function run (...result:number[]):string{
return '字符串'
}
or
function run (a:number,b:number...result:number[]):string{
return '字符串'
}
run(1,2,3,4,5) a就是1,b就是2 剩下的给result
4.函数重载 同(名函数)一个函数 传入不同的参数 实现不同的功能
function getInfo(name: string): string;
function getInfo(age: number): number;
function getInfo(str: any): any{
if(typeof str === 'string'){
return `${str}`;
}eles{
return str;
}
}
getInfo(20)
Ts中类的定义
定义一个类
class Person{
name: string; // 定义属性
constructor(n: string){ // 实例化类的时候触发的方法
this.name=n;
}
run(): void{
console.log(this.name)
}
}
var p = new Person('张三');
p.run() // 打印 张三
继承一个类
class Person{
name: string; // 定义属性
constructor(n: string){ // 实例化类的时候触发的方法
this.name=n;
}
run(): void{
console.log(this.name)
}
}
//继承
class Web extends Person {
constructor(name: string){ // super必须要有
super(name) // 用来调用父类的constructor方法 把name传过去 初始化父类的构造函数
}
}
var w = new Web('李四')
w.run() // 打印 李四
子类里面也可以实现自己的方法
如果子类里面有一个方法和父类相同 那就执行子类里面的方法 先去找自己有没有这个方法 如果自己上没有找到这个方法 则去父类里面找
类里面的修饰符(默认是public公有的)
public:公有的 在当前类,子类,类外面都可以访问
protected: 受保护的 在当前类里面,子类里面可以访问 在类外面不可访问
private: 私有的 在当前类里面可以访问,子类 类外面都访问不了
静态属性 静态方法
是指直接挂载到类本身上的属性和方法 访问的时候直接是类获取而不是实例化之后获取方法和属性
eg(Es5里面的写法):
function Person(){
this.run1=function(){
console.log('不是静态的方法,构造函数里的方法')
}
}
Person.run2 = function(){
console.log('静态方法')
}
Person.name = '静态属性'
// 访问静态属性和方法
Person.name // 打印 静态属性
Person.run2() // 打印 静态方法
eg(ts中写静态方法和静态属性 静态方法里没法直接调用类里面的属性 要想在静态方法里面访问类的属性 那也要定义一个静态的属性)
class Per{
public name: string;
public age: number=20;
static sex='男' // 静态属性
constructor(name: string){
this.name=name;
}
run(){
console.log('实例的方法')
}
static print(){
console.log(Per.sex,'访问类里面的静态属性')
console.log('静态的方法',this.name) // 这个位置应该是undefined 只能访问静态的方法
}
}
var p = new Per('入参')
Per.print()
多态 (父类定义一个方法不去实现,让继承他的子类去实现,每一个子类有不同的表现)属于继承的一种方式
eg:
// 父类 定义了一个eat方法 并没有具体实现
class Animal{
name: string;
constructor(name: string) {
this.name=name
}
eat(){
console.log('吃的方法')
}
}
// 继承的子类去实现
class Dog extends Animal{
constructor(name: string){
super(name);
}
eat(){
return this.name+'吃骨头'
}
}
class Cat extends Animal{
constructor(name: string){
super(name);
}
eat(){
return this.name+'吃鱼'
}
}
抽象类(用abstract关键字来定义抽象类)
ts中的抽象类 是提供给其他类继承的基类 不能直接被实例化 他是来定义是继承的那个类里面的标准的(例如上一个例子,继承他的子类里面可以没有eat方法 但是如果是抽象类 那就必须要有这个抽象的方法)
用abstract关键字定义抽象类和抽象方法,抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
抽象方法只能放在抽象类里面
eg:
abstract class Animal{
name: string;
constructor(name: string){
this.name = name;
}
abstract eat(): any; // 抽象方法 这个方法必须要在子类实现 不是抽象的方法可以不实现
}
// 继承他的子类
class Dog extends Animal{
constructor(name: string) {
super(name);
}
eat(){
return this.name+'吃骨头';
}
}
// 继承他的子类
class Cat extends Animal {
constructor(name: string){
super(name);
}
eat(){
return this.name+'吃鱼'
}
}
Ts接口
ts中接口就是规范 定义行为和动作的规范 就是一种标准
1.属性接口
函数传入的参数是个对象 对传入的对象进行一个约束 对批量的方法进行约束
function printInfo(labelInfo:{label: string}):void{
console.log(labelInfo,'传入的参数是对象类型')
}
// 调用 printInfo({label:'字符串'})
这个例子是一个函数的入参规范 如果有多个函数入参都是这个规范 那就需要接口来定义这个
eg属性接口:
// 这个就是传入的对象的约束 属性的接口定义
interface FullName{
firstName: string; // 分号结束
lastName: string;
}
// 具体实现
function printName(name:FullName){
console.log(name.firstName+'--'+name.lastName)
}
// 调用
var obj = {
age:20,
firstName: '张',
lastName: '三'
}
printName(obj) // 这种方法ok
// 下面这个写法会报错 因为接口里面没有age 而上面那种写法 只要包含接口里面定义的就行
printName({
age:20,
firstName: '张',
lastName: '三'
})
2.可选属性接口
eg可选属性接口:
// 这个就是传入的对象的约束 属性的接口定义
interface FullName{
firstName: string; // 分号结束
lastName?: string; // 可传可不传
}
// 具体实现
function printName(name:FullName){
console.log(name.firstName+'--'+name.lastName)
}
// 调用
printName({
firstName: '张',
})
3.函数类型接口
对方法传入的参数 以及返回值进行约束
eg函数类型接口:
interface encrypt {
(key: string,value: string):string;
}
const md5:encrypt = function(key: string, value:string): string{
return key+value;
}
console.log(md5('name','张三'))
4.可索引接口(对象/数组的约束 不常用)
1.可索引对数组的约束
eg:
interface UserArr{
[index: number]: string // 表示数组的索引值是number 数组里的每一个元素是string类型
}
var arr: UserArr = ['子1','子2']
console.log(arr[0])
2.可索引对对象的约束
eg:
interface UserObj{
[index: string]: string // 表示是一个对象
}
var arr1: UserObj = {name:'张三'}
5.类类型接口 是对类的约束 和抽象类似 必须要实现这个里面的属性和方法
implements 实现 这个关键字(写法)
// 定义一个类的接口
interface Animal{
name: string;
eat(str: string): void;
}
// 类里面去用这个接口
class Dog implements Animal{
name:string;
constructor(name: string){
this.name = name;
}
eat(){// eat里面不传参数也可以 但是这个方法必须要有
console.log(this.name + '吃骨头')
}
}
var d = new Dog('小黑')
d.eat()
接口的扩展 接口可以继承接口
eg:
// 定义一个父类接口
interface Animal{
eat():void;
}
// 接口继承
interface Person extends Animal{
work(): void;
}
// 创建一个父类
class Programmer {
name: string;
constructor(name: string){
this.name=name
}
coding(code:string){
console.log(this.name+code)
}
}
// 继承父类 并且实现Person接口
class Web extends Programmer implements Person{
constructor(name: string){
super(name);
}
eat(){
console.log(this.name+'吃零食')
}
work(){
console.log(this.name+'写代码')
}
}
var w = new Web('小李')
w.eat();
w.coding('写ts代码')
Ts泛型
泛型就是解决 类 接口 方法的复用性
1.泛型函数
泛型表示 用T关键字表示 具体表示什么类型 是调用这个方法的时候决定的 传入的参数和返回的参数类型一样
eg:
function getData<T>(value: T):T{
return value;
}
// 调用
getData<number>(123)
2.泛型类
eg:
// 创建一个类的泛型
class MinClass<T>{
public list:T[]=[];
add(value:T){
this.list.push(value);
}
min():T{
var minNum=this.list[0];
for(var i=0;i<this.list.length;i++){
if(minNum>this.list[i]){
minNum=this.list[i];
}
return minNum;
}
}
}
// 实例化一个类
var m1 = new MinClass<number>() // 实例化一个类 并且指定了T代表的是number类型
m1.add(1);
m1.add(2);
console.log(m1.min())
3.泛型接口
1.eg:
inetrface Config{
<T>(value:T):T;
}
var getData:Cofig = function<T>(value:T):T{
return value;
}
getData<string>('张三')
2.eg:
inetrface Config<T>{
(value:T):T;
}
function getData<T>(value:T):T{
return value;
}
var myGetData:Config<string>=getData;
myGetData('20') // 正确调用的
myGetData(20) // 错误调用的
4.把类作为参数类型的泛型类
麻烦的写法
class User{
username:string | undefined;
password:string | undefined;
}
class MysqlDb{
add(user: User):boolean{
return true;
}
}
var u = new User();
u.username='kk';
u.password='123456';
var Db = new MysqlDb();
Db.add(u)
eg正常的写法:
class MysqlDb<T>{
add(info:T):boolean{
return true;
}
class User{
username: string | undefined;
password: string | undefined;
}
var u = new User();
u.username='张三'
u.password='12344';
var Db = new MysqlDb<User>();
Db.add(u) // 正确写法
Db.add('ghhhh') // 错误写法