TS基础

81 阅读1分钟

定义

定义一个布尔值

let isDone:boolean = false

定义一个数值类型

let num:number = 1;

定义一个字符串

let myName:string = "Tom"

let str:string=`Hello,my name is ${myName}`

定义一个空值:void

function alterName(): void {
    alert("hello")
}

任意值any-允许赋值为任意类型

let myfavourite:any = 'seven'
myfavourite = 7;
console.log(myfavourite)
// 方法也是可以的
let anyThing:any = 'Tom';
anyThing.setName('Jerry');
anyThing.setName('Jerry').sayHello();

类型推论

let str;
str = 7;
str = 'seven';
str = false;
console.log(str)

联合类型

let myfavouriteName: string | number;
myfavouriteName = 'seven';
myfavouriteName = 7;

接口

在TS中,我们使用interface来定义一个接口类型的对象。

接口是对行为的抽象,而具体如何行动需要类去实现。

interface Person {
    name: string;
    age: number;
}
let tom: Person = {
    name: 'Tom',
    age: 25
}

任意属性

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}
let tom: Person = {
    name: 'Tom',
    age: 25
}

只读属性

readonly

数组

存放多个元素的集合

let temp: number[] = [1,2,3,4,,5,6]
// temp.push('7') 不能有其他类型
console.log(temp)
let temp1:any[] = [1,2,3,6,4,5,'7',true]
console.log(temp1)

函数 函数声明,函数表达式

// 函数声明
function sum(x:number,y:number):number{
    return x+y
}
sum(1,2)
// 函数表达式
let mySum = function sum(x:number,y:number):number{
    return x+y
}
// 如果手动指定类型
let mySum2: (x: number,y:number) =>number =function sum(x:number,y:number):number{
return x+y
}

通过接口定义函数的形状

interface SearchFunc{
(source:string,subString:string):boolean;
}

剩余参数...rest,重载

//
function push(array: any[],...items:any[]) {
    items.forEach(function(item){
        array.push(item);
    })
}
let a = [];
push(a,1,2,3,'4','5',true);
// 重载
function reverse(x:number|string):number|string|void{
    if(typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('')
    }
}
reverse(1)
reverse('1')

类型断言

将一个联合类型断言为一个指定类型,使用as关键字

interface Cat{
    name: string;
    run(): void;
}
interface Fish{
    name: string;
    swim(): void;
}
function isFish(animal: Cat|Fish) {
    if(typeof (animal as Fish).swim === 'function') {
        return true;
    }
    return false
}

将一个父类断言为更加具体的子类

class ApiError extends Error{
    code: number = 0;
}
class HttpError extends Error {
    statusCode: number = 200;
}
function isApiError(error: Error) {
    if(typeof (error as ApiError).code === 'number') {
        return true;
    }
    return false;
}

任何类型都可以断言为any

// 将一个变量断言为any是解决ts问题的最后一个手段
(window as any).foo = 1;
console.log((window as any).foo)
// 将any断言为更加具体的内容
function getCatchData(key: string): any{
    return (window as any).catch[key];
}
interface Cat {
    name: string;
    run(): void;
}

代码由不确定性向确定性的方向迁移

const tom = getCatchData('tom') as Cat;
tom.run()

类型断言的限制

并不是任何一个类型都可以断言为任何一个类型,两者之间有共同的属性或者方法,就可以互相断言

interface Animal {
    name: string;
}
interface Cat {
    name: string;
    run():void;
}
function testAnimal(animal:Animal){
    return (animal as Cat);
}
function testCat(cat:Cat) {
    return (cat as Animal)
}

双重断言--除非迫不得已,千万不能用

interface Cat{
    run(): void;
}
interface Fish{
    swim(): void;
}
function testCat1(cat:Cat){
    return (cat as any as Fish);
}

类型断言和类型转换

类型断言不会真正的影响变量类型

类型断言vs类型声明

a断言为b时,a和b有重叠的部分即可 a声明为b时,a必须具备b所有的属性和方法

const tom2 = getCatchData('tom') as Cat;
// 类型声明
const tom1:Cat = getCatchData('tom');
tom.run()

断言和泛型

function getCatchData1<T>(key:string): T {
    return (window as any).cache[key];
}
interface Cat {
    name: string;
    run():void;
}
const tom3 = getCatchData1<Cat>('tom')
tom.run()

使用type关键字定义类型别名和字符串字面量类型

type Name = string;
type NameResolver = () => string;
type NameOrResolver= Name | NameResolver;
function getName(n:NameOrResolver):Name{
    if(typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

元组

数组合并了相同类型的对象,而元组合并了不同类型的对象

let tom:[string,number] = ['tom',25]
console.log(tom[0],tom[1])

枚举--取值被限定在一定范围内的场景

enum Days {Sun,Mon,Tus};
console.log(Days["Sun"] === 0)
console.log(Days[0] === "Sun");

类 构造函数 属性 方法

定义了一件事物的抽象特点,包含它的属性和方法,面向对象三大特点 :封装继承多态 使用class定义类,使用constructor定义构造函数

class Animal {
    public _name;
    constructor(name:string) {
        this._name = name;
    }
    sayHi() {
        return `My name is ${this._name}`
    }
}
let a = new Animal('Jack');
console.log(a.sayHi());

类 存取器get set

class Animal1{
    constructor(name){
        this.name = name;
    }
    get name() {
        return 'Jack'
    }
    set name(value) {
        console.log('setter:' + value)
    }
}
let b = new Animal1('Kitty')
b.name = 'Tom'
console.log(b.name)

类,静态方法 使用static修饰

// public 全局的,公共的
class Animal3{
    public _name;
    constructor(name:string) {
        this._name = name;
    }
    sayHi() {
        return `My name is ${this._name}`
    }
    static sayHello(){
        return "hello"
    }
}
let a2 = new Animal3('Jack');
// 非静态方法,通过类的实例来调用
console.log(a2.sayHi())
// 静态方法使用static类修饰,使用的时候直接通过类来调用
console.log(Animal3.sayHello())
// private 私有的 只能在类的内部使用
// protected 受保护的,允许子类访问

类 参数属性和只读关键字

class Animal4{
    readonly name;
    public constructor(public name:string) {
        this.name = name
    }
}

抽象类

abstract 用于定义抽象类和其中的抽象方法

抽象类不允许被实例化

抽象类本身不能去实例化,需要通过子类去继承,然后由子类实现抽象类的方法

abstract class Animal5{
    public name;
    public constructor(name:string) {
        this.name = name;
    }
    public abstract sayHi():void
}
// let a = new Animal5('Jack')
class Cat extends Animal5{
    public sayHi() {
    console.log(`Memo,My name is ${this.name}`)
    }
}
let cat = new Cat('tom')
cat.sayHi()

类与接口

interface Alarm{
    alert():void;
}
class Door{}
class SecurityDoor extends Door implements Alarm{
    alert() {
        console.log('防盗门')
    }
}
class Car implements Alarm{
    alert() {
        console.log('Car alert')
    }
}

一个类可以实现多个接口

常见面向对象语言中,接口是不能继承类的,但是在Ts中是可以实现的

// 通过泛型来指定类型
function createArray<T>(length:number,value:T):Array<T>{
    let result:T[] = [];
    for(let i =0;i<length;i++) {
        result[i] = value;
    }
    return result;
}
// 可以不指定类型,通过类型推断类自动推断类型
createArray<string>(3,'x')

泛型 多个类型参数

function swap<T,U>(tuple:[T,U]):[U,T]{
    return [tuple[1],tuple[0]];
}
console.log(swap([7,'seven']))

泛型约束

interface Lengthwise{
length: number;
}

泛型接口

interface CreateArrayFunc<T>{
    (length:number,value:T):Array<T>;
}
let createArray1:CreateArrayFunc<string>;
createArray1 = function<T>(length:number,value:T):Array<T>{
    let result:T[] = [];
    for(let i = 0;i<length;i++){
    result[i] = value;
    }
    return result;
}
createArray1(3,'x')

声明合并,同名函数

如果定义了两个相同名字的函数,接口或类,那么它们会合并成一个类型

interface ALarm{
    price:number;
}
interface Alarm{
    weight: number;
}