青训营X豆包MarsCode 之TS学习 记录| 豆包MarsCode AI 刷题
众所周知,JS属于弱类型,和python一样有显著的缺点,也就是类型区分不明确等问题,所以也就有了TS的出现,相较于JS,TS更加的安全以及面向对象化,下面是一些自己的学习笔记以及总结出的可能出现的面试题,供大家参考
TS基础概念
什么是TS
她是JS的一个超集,在原有的语法基础上,添加了可选静态类型的和基于类的面向对象编程
TS原理
//1.源码输入
var a =2;
//2.扫描器- scanner=> 令牌流
[
'var': 'keyword'
'a:':identifier',
'=':'assignment',
'2':'iteger',
';':'eos'
]
//3.解析器- parser =>生成AST
{
operation:'=',
left:{
keyword:'var',
right:'a'
},
right:'2'
}
//4.绑定器 => symbol
//创建一个从AST节点到符号的引用连接(node,symbol) =>辅助工作
//5.校验器 - checker => 校验语法错误
//6.发射器 - emitter => 根据每个node翻译成js
TS与JS的区别
JS - 脚本化语言,用于面向简单额页面场景
TS - 面向解决大型复杂项目的,以及架构设计和代码维护
自主检测
JS - 运行时报错
TS - 编译时,主动发现问题并纠正错误
类型检测
JS - 弱类型,无静态类型选项
TS - 弱类型,支持类型检测,并且在预编译阶段可以进行提示
运行流程
JS- 可以在浏览器中执行的
TS - 依赖编译 TS转成JS再给浏览器
TS基础类型和写法
boolean | string | number |array |null |undefined
//es
let isEnabled= true
let course = 'zhaowa'
let classNum= 2
let u =undefined
let n =null
let classArr = ['basic','execute']
//ts
let isEnabled: boolean= true
let course: Sting = 'zhaowa'
let classNum: number= 2
let u: undefined =undefined
let n: null =null
let classArr: string[] = ['basic','execute']
let classARRY: Array<string>= ['basic','execute']//**断言**
tuple- 元组
let tupleType:[String,boolean]
tupleType=['zhaowa',true]
enum - 枚举
//数组类型枚举 - 默认从零开始,依次递增
enum Store {
BAD,//0
NG,//1
GOOD,//2
PREFECT//3
}
let score: Score = Score.BAD
//此处可以配合后端传参,后端需要的是值
字符串类型枚举
//数组类型枚举 - 默认从零开始,依次递增
enum Store {
BAD= 'BAD',
NG= 'NG',
GOOD= 'GOOD',
PREFECT='PREFECT'
}
大家想一想,如果同时出现数组和字符串,那么key值为0的是谁呢?
下面是一个例子
//数组类型枚举 - 默认从零开始,依次递增
enum Store {
YY,//0
BAD= 'BAD',
NG= 'NG',
GOOD= 'GOOD',
PREFECT='PREFECT',
ZHAOWA//1
}
//假如YY是5
//那么
//ZHAOWA 6
any | unknown | (void & never)
// any -绕过所有的类型检查
let anyValue :any =123
anyValue = 'anyValue'
anyValue = false
//unknown - 未知类型
let unknownValue:unknown =123
unknownValue= 'hell0' =>//类型检查无法通过
typeof unknownValue ===number &&unknuwnValue++
//面对unknown时候需要显示的进行检查才能应用
//void - 声明函数的返回值为空
function voidFunction():void {
console.log('no return')
}
//never - 声明函数永不返回
function error(msg:strting): never{
throw new Error(msg)
}
function longlongloop(): never{
while(true){
console.log('long loop')
}
}
object | Object
//objcet =>非原始类型(非int ...)
interface Object{
created(i:object | null):any
}
const zhaowa={}
Object.create(zhaowa)
//Object Object.prototype <=> {}
接口 - interface
对行为的抽象,具体的行为由类来实现
interface Class{ //接口
name:string;
time:number;
}
let zhaowa: Class={
name:'ts',
time:2
}
-
只读& 存在性
interface Class{ readonly name:string; //只读 time?:number //非必须 } //比如 let yy:Class={ name:'es' //没有time }
面试题: readonly 和 es的引用
const obj= 'zhaowa'//这里不能改
const obj= {
name:'zhaowa'
}
obj.name = 'yy' //可以的
obj= obj1 //不行 =>因为改变了地址
let arr:number[]=[1,2,3,4,5,6]
let ro:ReadonlyArray<number>=arr //只读就是不能改
ro[0]=12 //赋值不对
ro.push(7) //增加 - 不行
ro.length= 100 //不行
2.可添加
x interface Class{
readonly name:string;
time?:number;
[propName:string]:any //索引是sting,值是任何东西 //扩展
}
let yy:Class={
name:'js',
data:'9',
month:11,
year:'2024'
}
3.交叉类型
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:falsem,
e:'ts',
f:6
}
}
面试题:类型别名 type pk interface
相同点:
1.都可以用来描述对象函数
interface Class{
name:string
}
type Class={
name:string
}
2.都是可拓展
interface Course extends Class{
score:number
}
type Course= Class& {
score:number
}
不同点
1.联合计算
type Class= {
name:string
}
type Couse= {
nickName: string
}
type UnionClass = Class | Course
type TupleClass = [UnionClass,Course]
//interface多次定义
interface Class{
name:string
}
inrerface Class{
nickName:string
}
//type小能力
type Keys = 'name' | 'nickName'
type Class ={
[key in Keys]:string
}
面试:联合冲突
interface A{
c:string;
d:string;
}
interface B {
c:number;
e:string;
}
type AB = A & B
let ab:AB = {
c:nerver
//联合冲突看标识符 或就是string| number 否则nerver
}
断言 - 变量类型多样化
//尖括号
let anyValue:any ='zhaowa' //免死金牌了下面都不检查
let anyLength: number = (<string>anyValue).length
//as声明
let anyValue:any ='zhaowa'
let anyLength: number = (anyValue as string).length
//非空
type ClassTime =() =>number
const start = (classTime:ClassTime |undefined) =>{
let num = classTime!()
}
类型守卫 - 保障语法规定的多种范围之内,做校验
interface Teacher {
name:string;
course:string[];
}
interface Student {
name:string;
startTime:string;
}
type Class = Teacher | Student
function startCourse(cls:Class) //老师 |学生
{
if('course' in cls){
//Teacher
}
}
泛型
function startClass<T,U>(name: T.score: U): T{
return name+score
}//传入类型T 和 U 返回时和name一样的 T
function startClass<T,U>(name: T.score: U): string{
return (name+Sring(score)) as T
}
装饰器
function Zhaowa(target : Function): void {
//target加工
target.prototype.startClass= function():void
}
function nameWrapper(target:any,key:string):void
{
....
}
@Zhaowa
class Class {
constructor(){}
@nameWrapper
name:string
}
重载
class Course{
start(name:number,score:number):number;
start(name:string,score:number):any;
start(name:Combinable,score:Combinable){
if(typeof name === 'string' ||typeof score === 'string')
{do ......}
}
总结
TS在项目中多使用装饰器与类型,注意装饰器在不同场景中的使用,并且在学习以及复习中,要将TS与实际场景运用结合起来。在同一个项目编写的时候,可以将同一个功能分别用TS和JS写,进行对比。