Ts基础概念
什么是Ts
对比原理
ts是一个JS的一个超集,在原有的基础上,添加了可选静态类型,基于类的面向对象编程
1.编写项目-更利于架构维护
2.自主检测-编译期间检测
3.类型检测-支持了动态和静态类型检测 => 本质存在类型转换(面试:ts是强类型语言吗?答:本质上不是)
4.运行流程-依赖编译
5.复杂特性-模块化、泛型、接口
一.基础类型
*基本类型(string/number/array/boolean/null/undefined)
let str:string = 'abc'
let num:number = 1
let isTrue:boolean = true
let arr:string[] = ['a','b','c']
let arr:Array<number> = [1,2,3]
*tuple - 元组
let tupleType:[string,number]
tupleType = ['ts',true]
*enum - 枚举
/**数字枚举-从0开始,依次递增 */
enum Score {
PERFECT,
GOOD,
NG,
BAD
}
let score:Score = Score.PERFECT //0
let score:Score = Score[0] //'PERFECT' /**反向映射 */
/**字符串枚举 */
enum Score {
PERFECT = ''PERFECT",
GOOD = "GOOD",
NG = "NG",
BAD = "BAD",
}
/** 异构 */
enum Score {
PERFECT, //0
GOOD = “GOOD”, //GOOD
NG = 6, //6
BAD //7
}
*any unknown void never
/** any - 绕过所有检查 => 类型检测和编译筛查全部失效 */
let anyValue:any = 123
anyValue = 'anyValue'
/** unknown - 绕过赋值检查 => 禁止更改传递 */
let unknownValue:unknown = "unknown"
let value1:unknown = unknownValue //OK
let value2:any = unknownValue //OK
let value3:boolean = unknownValue //NO
/** void - 声明函数返回值 */
function voidFunction(): void{
console.log('no return')
}
/** never - 永不返回 */
function error(msg:string):never{
throw new Error(msg)
}
function longloop():never{
while(true){}
}
*object | Object | {} - 对象
//object - 非原始类型(除其他原始类型以外的)
interface ObjectConstrutor{
create(o: object | null) : any
}
const proto = {
a:1
}
Object.create(proto) //OK ts2.2推出的方法
Object.create(null) //OK
Object.create(‘abc’) //NO
//Object - 原型属性(接受除了null和undefined任何类型的值,所有值都是Object的实例)
//Object.prototype上属性
interface Object{
constructor: Function;
toString(): string;
valueOf(): Object;
}
let a:Object = 123 //OK
let a:Object = 'abc' //OK
let a:Object = [ 'abc','d'] //OK
let a:Object = () => {} //OK
//{} - 空对象 可以接受除了null和undefined之外的任何类型的赋值
function fn(params:{}){}
fn(1) //OK
fn('abc') //OK
fn(null) //ON
const a = {}
a.age = 10 //NO
二、接口 - interface
*对行为的抽象,具体行为由类实现
interface Person{
name:string;
age:number;
}
let person:Person = {
name: 'Jom',
age:10
}
//只读
interface Person{
readonly name:string;
age:number;
}
//任意
interface Person{
readonly name:string;
age:number;
[favorite:string]:any;
}
//面试 - 和JS的引用不同
let arr:number[] = [1,2,3]
let ro:ReadonlyArray<number> = arr //只读
ro[0] = 10 //Error - 不能赋值
ro.push(5) //Error - 不能增加
ro.length = 10 //Error - 不能改变长度
arr = ro // Error -不能赋值
三、交叉类型
1、合并
interface A{x:D}
interface B{x:F}
interface D{name:string}
interface F{age:number}
type AB = A&B
let obj:AB = {
x:{
name:'Tom',
age:9
}
}
2、合并冲突
inferface A{name:string;age:number}
inferface B{name:number;favorite:string}
type AB = A&B //合并是且的关系 => c:never
四、断言 - 类型声明、转换
//尖括号
let anyValue:any = 'hi'
let anyLength:number = (<string>anyValue).length //阶段性声明
//as声明
let anyLength:number = (anyValue as string).length
//非空判断
type ClassTime = () => number
const start = (classname:Classname|undefined)=>{
let num = classname!() //确定一定不为空
}
//面试
const tsClass:number|undefined = undefined
const course:number = tsClass!
//使用意义 =>告知编译器,运行时,会被赋值
五、类型守卫
interface Teather{
name: string;
courses:string;
score:number;
}
interface Student{
name: string;
startTime:number;
score:string;
}
type Class = Teather | Student
function startCourse(cls:Class){
if('courses' in cls){//Teather逻辑}
if('startTime' in cls){//Student逻辑}
}
function startCourse(cls:Class){
if(cls instanceof Teather){//Teather逻辑}
if(cls instanceof Student){//Student逻辑}
}
function startCourse(name:string,score:string | number){
if(typeof score === 'number'){//Teather逻辑}
if(typeof score === 'string'){//Student逻辑}
}
六、TS进阶
1.泛型
//T U K 键值 | V 值 | E 节点
function startClass<T,U>(name:T,age:U):T{
return name + score
}
startClass<string,number>('jack',9)
function startClass<T,U>(name:T,age:U):string{
return `${name}${age}`
}
function startClass<T,U>(name:T,age:U):T{
return (name + String(score)) as any as T
}
2、装饰器 - decorator
function Dec(target:Function):void{
target.prototype.startClass = function():void{}
}
function Atr(target:any,key:string){
//逻辑
Object.defineProperty(target,key,()=>{}) //属性劫持
}
//类装饰器
@Dec
class Course{
constructor(){}
//属性装饰器
@Atr
public name:string
}
//方法装饰器
ts原理解析
// 1.源码输入
let a:number = 2
// 2.scanner扫描器扫描 => 识别内容范围生成数据流
[
"let": "keyword",
"a":"identifier",
"=":"assignment",
"2":"integer",
";":"eos" (end of statement)
]
//number
//3.解析器 parser 生成语法树 - AST
{
operation:"=",
left:{
keyword: 'var',
//...
}
}
//4.绑定器 binder 主要职责 创建symbols
//node.symbol
//5.校验器 checker 检查TS语法错误 => 检查器中进行的
//6.发射器 emitter 根据每个节点的检查结果产出node翻译成js