TypeScript入门

302 阅读5分钟

1,强类型和弱类型(类型安全)

强类型:在语言层面,函数的实参类型必须与形参类型相同;

弱类型:在语言层面不会限制实参的类型;

强类型有更强的类型约束,而弱类型几乎没有任何约束;

强类型语言中不允许任意的隐式类型转换,而弱类型语言中允许任意的隐式类型转换;

变量类型允许随时改变的特点,不是强弱类型的差异;

2,静态类型和动态类型(类型检查)

静态类型:一个变量在声明时它的类型就是明确的,声明过后,它的类型不允许再改变;

动态类型:在允许阶段才能明确变量的类型,而且变量的类型可以随时改变;

3,typeScript

typeScriptjavascript的超集;

安装:yarn add typescript --save-dev

编译:yarn tsc index.ts

配置文件:运行yarn tsc --init会自动生成tsconfig.json配置文件,文件中包含所有的配置信息,配置好配置文件再运行yarn tsc就会对整个项目进行编译。

标准库就是内置对象所对应得声明;

4,声明基础类型

let str:string = 'xxx';//声明字符串
let a:number = 2;//声明数字
let b:boolean = true;//声明boolean类型
let u:undefined = undefined;//声明undefined
let n:null = null;//声明null
let c:any = 12;//声明any类型,类型可以随意改变

void:void类型像是与any类型相反,它表示没有任何类型。当一个函数没有返回值时,通常使用void表示:

function func():void{console.log(0)};

5,Object类型

object类型并不单指对象,而是原始类型以外的其它类型;对象的限制,可以使用类似对象字面量的方式,但更专业的方式是使用接口;

const foo:object = function(){} | [] | {};

如果需要限制对象类型,则应该使用这种类型对象字面量的语法,或者使用接口:

const foo:{a:string,b:number} = {a:'a',b:1};

6,数组类型

数组有两种形式:

const arr:Array<number> = [1,2,3];
const temp:number[] = [1,2,3];

7,元组类型

元组就是一个明确元素数量以及每个元素类型的数组:

const arr:[string,number] = ['abc',123];

8,枚举类型

标准的数字枚举,枚举值自动基于前一个值自增; 默认从0开始

enum postdata {
	first,//0
    secont,//1
    sret,//2
}

也可以自定义开始的值:

enum postdata {
	first = 5,
    secont,//6
    sret,//7
}

常量枚举,不会侵入编译结果:

const enum postData {
	first,
    secont,
    sret,
}

9,函数类型

函数中如果某一个参数是非必填的,则在参数后面加一个?表示:b?:number;

function func(a:number,b?:number):string{ return 'func'}
func(123,234);
func(123);

10,隐式类型推断

在没有给变量设置类型时,typescript会进行隐式类型推断,可能会引起不必要的错误,建议给每个变量设置类型;

11,类型断言

在某些情况下typescript不能准确判断变量的类型,比如:

//假设这个arr来自于一个明确的接口
const arr = [123,456,789];

const result = arr.find((v) => v > 0);//在这里typescript推断result是number或者undefined;

const squery = result * result;//在这里使用乘法时就会报错;

类型断言,就是明确告诉typescript result一定是number;

const num1 = result as number

或者

const num2 = <number>result;// JSX 下不能使用

12,接口

接口是为了约束对象的结构,只是为对象属性进行类型约束;

interface Post {
	title:string,
    count:string
}

function func(post:Post){ ... };

func({
	title:'javascript',
    count:'lean'
})

可选成员,在属性后面加一个问号,就表示该属性可以有也可以没有:

interface Post{
	title:string,
    count:string,
    auth?:string
}

只读成员,在属性名称前面加上readonly修饰符,就表示该属性设置值之后就不可以再修改:

interface Post {
	readonly title:string
}
let post:Post = {title:'javascript'};
post.title = 'vue';//报错,title是只读属性,不可更改;

动态成员,对象的属性名是不确定的,会动态修改:

interface Post {
	[key:string]:string
}

13,类

类:描述一类具体事物的抽象特征;typescript中类的属性必须要提前声明;

class Person {
	name:string;
    constructor(name:string){
    	this.name = name;
    }
}

类的访问修饰符:public:公有属性,能在实例中访问;private:私有属性,不能在实例中访问;protected:私有属性,可以被继承,不能在实例中访问;

class Person {
	public name:string;
    private age:number;
    protected gender:boolean;
}

类的只读属性:readonly,跟在访问修饰符之后:

class Person {
	public name:string;
    private age:number;
    protected readonly gender:boolean;
}

类与接口:implements

interface Eat{
	eat (food:string) :void;
}
interface Run{
	run (step:number) :void;
}
class Person implements Eat,Run {
	eat (food: string): void {
    console.log(`优雅的进餐: ${food}`)
  }

  run (distance: number) {
    console.log(`直立行走: ${distance}`)
  }
}

抽象类:只能被继承,不能创建实例,abstract;

abstract class Animal {
	eat (food: string): void {
    console.log(`呼噜呼噜的吃: ${food}`)
  }

  abstract run (distance: number): void
}

class Dog extends Animal {
  run(distance: number): void {
    console.log('四脚爬行', distance)
  }

}

const d = new Dog()
d.eat('嗯西马')
d.run(100)

14,泛型

泛型:就是在定义接口或者类的时候不去指定参数类型,等到使用的时候再去指定类型的特征;

function creatArr<T>(lean:number,value:T):T[]{
	const arr = Array<T>(lean).file(value);
    return arr;
}

const res = creatArr<string>(2,'foo');

15,类型声明

对应没有使用typescript写的npm包,要么下载它的类型声明包,或者使用declare语句自己确定类型声明;

import { camelCase } from 'lodash';

declare function camelCase (input:string):string;

const res = camslCase('hello typescript');