typescript
文章目录
前言
ts基础内容。
一、什么是TS?它和JS有何不同?
A 对比原理
他是JavaScript的一个超集,在原有的语法基础上,添加了可选的静态类型和基于类的面向对象编程。
面向项目
TS:面向于解决大型复杂项目中,架构以及代码维护复杂场景
JS:脚本话语言,用于面向单一场景
自主检测
TS:编译期间,主动发现并纠正错误
JS:运行时报错
类型检测
TS:弱类型,支持对于动态和静态类型的检测
JS: 弱类型,无静态类型选项
运行流程
TS:依赖编译,依赖工程化体系
JS: 直接在浏览器中运行
复杂特性
TS:模块化、泛型、接口
B. 安装运行
npm install -g typescript
tsc -v //打印版本号
tsc test.ts // 编译ts文件
// .ts => .js => 浏览器执行环境
// 知识点:所有的类型检测和语法检测 => 编译时进行
二、TS基础类型与写法
- boolean、string、number、array、null、undefined
// es
let isEnabled = true;
let class = 'myClass';
let classNum = 2;
let u = undefined;
let n = null;
let classArr = ['basic', 'execute']
// ts
let isEnabled: boolean = true;
let class: string = 'myClass';
let classNum: number = 2;
let u: undefined = undefined;
let n: null = null;
let classArr: string[] = ['basic', 'execute']
let classArr: Array<string> = ['basic', 'execute']
- tuple - 元组
// ts
let tupleType: [string, boolean];
tupleType = ['myClass', true];
- enum - 枚举
// 数字类枚举 - 默认从零开始,从上到下依次递增
enum Score {
BAD, // 0
NG, // 1
GOOD, // 2
PERFECT // 3
}
let sco: Score = Score.BAD; // 0
// 字符串类型枚举
enum Score {
BAD = 'BAD',
NG = 'NG',
GOOD = 'GOOD',
PERFECT = 'PERFECT'
}
let sco: Score = Score.BAD; // 'BAD'
// 反向映射
enum Score {
BAD, // 0
NG, // 1
GOOD, // 2
PERFECT // 3
}
let scoName = Score[0]; // BAD
let scoVal = Score['BAD']; // 0
// 异构
enum Enum {
A, // 0
B, // 2
C = 'C', // C
D = 'D', // D
E = 6, //6
F, // 7 找上一个数字类型,然后递增,所以是 7
}
// 知识点:指出异构的枚举值
// 知识点:手写将其转化为JS实现
let Enum;
(function(Enum) {
// 正向
Enum['A'] = 0;
Enum['B'] = 1;
Enum['C'] = 'C';
Enum['D'] = 'D';
Enum['E'] = 6;
Enum['F'] = 7;
// 反向
Enum['0'] = 'A';
Enum['1'] = 'B';
Enum['6'] = 'E';
Enum['7'] = 'F';
})(Enum || (Enum = {}));
- any unknown void
// any - 绕过所有类型检查 => 类型检测和编译筛查全部失效
let anyValue: any = 123;
anyValue = 'anyValue'; // 赋值为字符串
anyValue = false; // 赋值为布尔
let value1: boolean = anyValue; // 赋值给别的变量
// unknown - 绕过了赋值检查 => 禁止更改传递
let unknownValue: unknown;
unknownValue = true;
unknownValue = 123;
unknownValue = 'unknownValue';
let value1: unknown = unknownValue;// ok
let value2: any = unknownValue; // ok
let value3: boolean = unknownValue; // nok
// void - 声明函数的返回值 未 return;
function voidFunction(): void {
console.log('void function')
}
// never - 函数永不返回
function error(msg: string): never {
throw new Error(msg)
}
function longlongLoop(): never {
while(true) {}
}
- object / {} - 对象
接口 - interface
对行为的一种抽象,不代表任何业务逻辑,也没有任何值,具体行为由具体类实现
interface Class {
name: string;
time: number;
}
let myClass: Class = {
name: 'ts',
time: 2
}
// 只读 & 任意
interface Class {
readonly name: string;
time: number;
}
// 知识点 - readonly 和 JS 的引用是不同的 < = > const => 执行阶段不同
let arr: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = arr;
ro[0] = 12;
ro.push(5);
ro.length = 100;
arr = ro;
// 以上全部报错ERROR; const 修改指针对应的值是允许的,readonly是不允许修改任意值的。
// 任意
interface Class {
readonly name: string;
time: number;
[propName: string]: any;
}
const c1 = {name:'JS', time: 1}
const c2 = {name: 'browser', time: 1}
const c3 = {name: 'TS', level: 1, time: 2}
交叉类型
// 合并
interface A {x: D}
interface B {x: E}
interface C {x: F}
interface D {d: boolean}
interface E {e: string}
interface F {f: number}
type ABC = A & B & C;
let abc: ABC = {
x: {
d: false,
e: 'myClass',
f: 5
}
}
// 合并冲突
interface A {
c: string,
d: string
}
interface B {
c: number,
e: string
}
type AB = A & B;
let ab: AB = {
d: 'class',
e: 'clcass'
}
// => 且关系 => c: never
// 合并时需要注意丢失参数的风险
断言 - 类型声明和转换 (开发者和编译器的告知交流)
编译状态在产生作用
// 尖括号 的形式做阶段性的类型声明
let anyValue: any = 'hi myClass';
let anyLength: number = (<string>anyValue).length;
// as声明
let anyValue: any = 'hi myClass';
let anyLength: number = (anyValue as string).length;
// 非空 ! - 只判断不为空
type ClassTime = () => number;
const start = (classTime: ClassTime | undefined) => {
let num = classTime!();// 具体类型待定,但是非空是确认的
}
// 使用场景 通用中台处理逻辑
const tsClass: number | undefined = undefined;
const myClass: number = tsClass!;
// 底层实现后,上层应用
const tsClass = undefined;
const myClass= tsClass; // undefined
//肯定化保证
let score: number;
startClass();
console.log(2 * score);
function startClass() {
score = 5;
}
let score!: number; // 告知编译器,运行时会被赋值
类型守卫 - 保障语法规定的范围内,额外的确认
interface Teacher {
name:string;
courses: string[]
}
interface Student {
name: string;
startTime: Date;
}
type Class = Teacher | Student;
//in - 是否包含某种属性
functiong startCourse(cls: Class){
if('courses' in cls){
//老师
}
if('startTime' in cls){
//学生
}
}
// typeof / instanceof - 类型分类场景下的身份确认
functiong startCourse(cls: Class){
if(typeof cls.score === 'number'){
//老师
}
if(typeof cls.score === 'string'){
//学生
}
}
functiong startCourse(cls: Class){
if(cls instanceof Teacher){
//老师
}
if(cls instanceof Student){
//学生
}
}
// 自定义类型
const isTeacher = function (cls: Teacher | Student): cls is Teacher {
// 老师。。。
}
const getInfo = (cls: Teacher | Student) => {
if(isTeacher(cls)){
return cls.courses;
}
}
TS进阶方案
1.函数重载
class Class {
start(name: number, score: number): number;
start(name: string, score: string): string;
start(name: string, score: number): number;
start(name: Comnbinable, score: Comnbinable){
if(typeof name ==='string' || typeof score ==='string'){
}
if(typeof name ==='number' || typeof score ==='number'){
}
if(typeof name ==='string' || typeof score ==='number'){
}
}
}
2.泛型-重用
function startClass <T, U>(name: T,score: U): T{
//
}
function startClass <T, U>(name: T,score: U): string{
//
}
function startClass <T, U>(name: T,score: U): T{
return (name + String(score)) as any as T;
}
3.装饰器 - decorator
// 类装饰器
function myClass(target: Function):void {
target.prototype.startClass = function(): void {
// 逻辑
}
}
@myClass
class Course {
constructor() {
//业务逻辑
}
}
// 属性/方法装饰器
function nameWrapper(target: any, key: string): void {
Object.defineProperty(target, key, {})
}
class Course {
constructor() {
// 业务逻辑
}
@nameWrapper
public name: string;
}
TS原理流程
// 1.源码
var a =3;
// 2.scanner扫描器生成令牌流
[
'var': 'keyword',
'a': 'identifier',
'=': 'assignment',
'3': 'imteger',
';': 'eos'
]
// 3. parser 解析器
{
operation:'=',
left: {
keyword: 'var',
right: 'a'
}
right: '3'
}
// 4. binder 绑定器
// AST节点 node.symbol <=> 辅助校验器
// 5.1校验器checker
// ts节点语法检查 => 类型检查
// 5.2 发射器emitter
// 翻译完成每个node节点的内容,翻译成js => 输出
总结
以上就是今天要讲的内容,本文仅仅简单介绍了ts的原理和基本使用。