1. 什么是TS?
TS是强类型的JS超集,支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等。
TS并不直接在浏览器上运行,需要编译器编译成JS来运行。
2. TS的主要特点
- 跨平台:可以安装在任何OS上
- ES6特性
- 是面向对象的语言,提供标准OOP功能
- 使用静态类型并帮助在编译时就进行类型检查
- 允许可选的静态类型
- 可以操作DOM来增删客户端网页元素
3. any、never、unknown、null & undefined、void有什么区别?
any:动态的变量类型(失去类型检查的作用)
never:永不存在的值的类型。例如:never类型是那些总是会抛出异常 或 根本不会有返回值的函数表达式
unknown:任何类型的值都能赋给unknown类型,但unknown类型的值只能赋给unknown本身 和 any类型
null&undefined:默认下它们是所有类型的子类型
void:没有任何类型。例如:一个函数没有返回值,就可以把返回值定义为null
4. any和unknown的区别
unknown更严格,在对unknown类型的值执行大多数操作之前,必须进行某种形式的检查。
而对any执行操作之前,不必做任何检查。
在编程阶段还不清除类型的变量,比如来自用户输入 或 第三方代码库,我们又不希望类型检查器对这些值进行检查而直接通过编译阶段的检查,这时就可以用any。
5. 如何将unknown指定为一个具体的类型
- 使用typeof进行类型判断
- 对unknown使用类型断言,注意的是:断言错了语法能通过,但运行会报错
6. const和readonly的区别
const防止变量的值被修改
readonly防止变量的属性被修改
7. TS的this 和 JS的this有什么差异?
TS中,在nolmplicitThis: true的情况下,必须声明this的类型,才能在函数或对象中使用this
箭头函数的this和ES6中箭头函数的this是一致的
8. 命名空间与模块的理解 区别
模块:跟ES6一样,任何包含import或export的文件都被当成一个模块,如果一个文件没有import或export的声明,就视为是全局可见的。
命名空间:定义了标识符的可见范围,主要是解决重名问题。
区别:都可以包含代码和声明,但模块可以声明它的依赖。
9. 简要介绍一下TS模块的加载机制
假设有一个导入语句:import { a } from “moduleA”
(1)编译器通过绝对或相对路径,定位到需要导入的模块文件
(2)如果上面解析失败了,没有查找到对应的模块,编译器会尝试定位一个外部模块声明
(3)最后,还是不能解析这个模块,就直接抛出一个错误
10. 实现一个判断入参是否是数组类型的方法
function isArray(x: unknown): boolean {
if (Array.isArray(x)) {
return true;
}
return false;
}
11. interface和type的区别
相同点:
- 都可以描述 对象或函数
- 都允许扩展,两者不是相互独立的
不同点:
- type可以声明基本类型、联合类型、元组
- type可以使用 typeof 获取实例的类型进行赋值
- 多个相同的interface声明可以自动合并
使用interface描述 数据结构,使用type描述 类型关系
12. 支持的访问修饰符有哪些?
public:类的所有成员、子类、类的实例都能访问
protected:类及子类的所有成员能访问
private:只有类的成员能访问
如果未指定访问修饰符,则它是隐式公共,这符合TS的便利性。
13. 方法重写是什么?
子类具有和父类中声明相同的方法,就是方法覆盖,换句话说,在派生类或子类重新定义基类方法
- 方法要与父类名称一样
- 参数要相同
- 必须有继承
14. 对象展开有什么副作用?
展开对象后面的属性会覆盖前面的属性
仅包含对象自身的可枚举属性,不可枚举的属性将会丢失
15. 什么是TS映射文件?
TS Map文件是一个源映射文件,其中有关原始文件的信息。
- .map是源映射文件,在JS代码和创建它的TS源文件之间进行映射
- 调试调的是TS文件
16. 类型有哪些?
- 内置:数字、字符串、布尔值、void、null、undefined
- 用户定义:枚举、类、接口、数组、元组
17. TS中什么是类型接口?
- 接口用于一个类的话,那接口会表示行为抽象
- 对类的约束,让类去实现接口,类可以实现多个接口
- 接口只能约束类的公有成员
18. 泛型是什么?
提供创建可重用组件的方法的工具,它能够创建可以使用多种数据类型而不是单一数据类型的组件,允许创建泛型类、泛型函数、泛型方法和接口。
在泛型中,类型参数写在左括号和右括号之间,这使它成为强类型集合,它使用一种特殊的类型变量来表示类型。
19. getter/setter
getter允许引用一个值但不能编辑它;setter允许改变变量的值,但不能查看当前值
20. 什么是装饰器?
装饰器是一种特殊的声明,允许通过使用@<name>
注释标记来一次性修改类 或 类成员。每个装饰器都必须引用一个将在运行时评估的函数。
21. mixin
本质是在相反方向上工作的继承,mixins允许通过组合 以前类中更简单的不分类设置 来构建新类
22. 什么是类型断言?
类似于其它语言的类型转换,它对运行时没有影响,仅仅由编译器使用。
本质是类型转换的软版本,建议编译器将变量视为某种类型,但如果处于不同形式,不会强制它进入该模型。
23. 什么是JSX?
JSX是带有不同扩展名的JS,JSX是一种可嵌入的类似xml的语法,它将被转成JS,要使用JSX,需要使用.tsx扩展名命名文件、启用JSX选项
24. 什么是Rest参数?
rest参数用于向参数传递0个或多个值,它通过在参数前加上…来声明,它允许在函数不使用arguments对象的情况下拥有可变数量的参数。
要遵循以下规则:
- 一个函数只允许一个rest参数
- 必须是数组类型
- 必须是参数列表中的最后一个参数
25. 对TS兼容性的理解
类型兼容:Y可以赋值给另一个类型X,就说X兼容类型Y
接口兼容:X=Y 只要目标类型X中声明的属性变量在源类型Y中都存在就是兼容的
函数兼容:X=Y Y的每个参数必须都在X里找到对应类型的参数,参数名字无所谓,只看类型
26. declare,declare global是什么?
declare用来定义全局变量、全局函数、全局命名空间
declare global为全局对象window增加新的属性
27. keyof和typeof关键字的作用
keyof:获取索引类型的属性名,构成联合类型
typeof:获取一个变量或对象的类型