知识点
- 基础类型
- 变量声明
- 函数
- 泛型
- 类
- 模块
- 异步编程
- 高级类型
- 类型注解和类型推断
- ts配置
- 声明全局变量、库、.d.ts
面试题
概况:说说你对ts的理解?与js的区别?
- 是一种静态类型语言,提供了类型注解,在代码编译阶段就可以检查数据类型的错误。
- 是Javascript的类型超集,支持es6语法,支持面向对象编程的概念,如类、接口、继承、泛型等。
基础类型
TypeScript中的类型有哪些?
- 内置:包括数字、字符串、布尔值、无效(void)、空值null和未定义undefined
- 用户定义:枚举、类、接口、数组、元组
ts中any和unknown有什么区别?
any
类型是一种弱类型,它放宽了类型检查;而 unknown
类型是一种强类型,它需要进行类型检查才能进行操作。尽量避免使用 any
类型,而是优先使用 unknown
类型来增加类型安全性。
如何将unknown类型指定为一个更具体的类型?
- 使用typeof进行类型判断
- 对unknown类型使用类型断言,注意地,断言错了时语法能通过检测,但是运行的时候就会报错了。
TypeScript中never和void的区别
void
类型:void
表示没有返回值的函数类型或变量类型。它通常用于表示函数没有返回任何值。在变量类型中,可以将其用作一种占位符,表示没有指定具体的类型。never
类型:never
表示永远不会发生的类型。它通常用于表示函数抛出异常、进入无限循环或永远不会返回的情况。如果一个函数永远不会返回(例如,总是抛出异常),那么该函数的返回类型应为never
。
TypeScript中interface和type的差别是什么?
- 相同点:
- 都可以描述一个对象或者函数;
- 都允许拓展,interface可以extends type,type也可以extends interface
- 不同点:
-
type可以声明基本类型别名,联合类型,元组等类型;
-
type语句中还可以使用typeof获取实例的类型进行赋值;
-
interface能够声明合并。
-
interface
可以通过extends
关键字来扩展其他接口或类,实现接口的继承。而type
可以使用交叉类型(&
)来实现类型的合并。
-
变量声明
TypeScript中什么是装饰器,它们可以应用于什么?
装饰器(Decorators)是一种 TypeScript 中的特殊声明,用于修改类、方法、属性或参数的行为。它们提供了一种在运行时修改类及其成员的能力。
装饰器可以应用于以下几个地方:
- 类装饰器(Class Decorators):应用于类声明之前,用于修改类的行为或元数据。类装饰器接收类的构造函数作为唯一的参数。
- 方法装饰器(Method Decorators):应用于方法声明之前,用于修改方法的行为或元数据。方法装饰器接收三个参数:目标对象(类的原型)、被装饰的方法的名称和描述符。
- 属性装饰器(Property Decorators):应用于属性声明之前,用于修改属性的行为或元数据。属性装饰器接收两个参数:目标对象(类的原型)和属性的名称。
- 参数装饰器(Parameter Decorators):应用于函数或方法的参数声明之前,用于修改参数的行为或元数据。参数装饰器接收三个参数:目标对象(类的原型)、方法的名称和参数在函数参数列表中的索引。
装饰器可以用来实现许多功能,例如:
- 添加日志记录或性能监控
- 实现身份验证或权限控制
- 修改类的原型或属性
- 收集元数据信息等
TypeScript中的类型断言是什么?
类型断言(Type Assertion)是一种方式,用于告诉编译器某个值的具体类型。它允许开发者手动指定变量或表达式的类型,以便在编译时进行类型检查。
类型断言有两种语法形式:
- 尖括号语法:
let strLength: number = (<string>someValue).length;
- as 语法:
let strLength: number = (someValue as string).length;
keyof和typeof关键字的作用?
函数
- 函数类型
- 可选参数和默认参数
- Rest 参数
- 函数重载
类
- 类的基本用法
- 继承
- 访问修饰符
- 抽象类
- 静态属性和方法
- 接口实现
泛型
TypeScript中泛型是什么?
是提供创建可重用组件的方法的工具,它能够创建可以使用多种数据类型而不是单一数据类型的组件。而且,它在不影响性能或生产率的情况下提供了类型安全性。泛型允许我们创建泛型类、泛型函数,泛型方法和泛型接口。
模块
- 导出和导入
- 默认导出
- 命名空间
异步编程
- 回调函数
- Promise
- async/await
- Generator
类型注解和类型推断
聊聊你对TypeScript类型兼容性的理解?
TypeScript的类型兼容性是指在使用不同类型的变量之间进行赋值或参数传递时,TypeScript编译器对其是否兼容的判断机制。
-
ts类型兼容:当一个类型 Y 可以赋值给另一个类型 X 时, 我们就可以说类型 X 兼容类型 Y。也就是说两者在结构上是一致的,而不一定非得通过 extends 的方式继承而来。
-
接口的兼容性:
X = Y
只要目标类型 X 中声明的属性变量在源类型 Y 中都存在就是兼容的( Y 中的类型可以比 X 中的多,但是不能少) -
函数的兼容性:
X = Y
Y 的每个参数必须能在 X 里找到对应类型的参数,参数的名字相同与否无所谓,只看它们的类型(参数可以少但是不能多。与接口的兼容性有区别)
对协变、逆变、双变和抗变的理解?
协变、逆变、双变和抗变是类型系统中用于描述不同类型之间关系的术语:
- 协变(Covariance):在一个类型系统中,如果子类型可以隐式转换为父类型,则称为协变。在协变关系下,子类型的派生程度大于或等于父类型。简单来说,协变允许将派生类的对象赋值给基类的引用。
- 逆变(Contravariance):与协变相反,逆变是指父类型可以隐式转换为子类型。在逆变关系下,子类型的派生程度小于或等于父类型。通常在函数参数上使用逆变,使得可以传入更为特定的类型。
- 双变(Bivariance):双变是同时具备协变和逆变特性的关系。这意味着类型可以在协变和逆变的位置都进行隐式转换。某些类型系统支持双变,但需要谨慎使用,因为它可能导致类型安全问题。
- 抗变(Invariance):抗变是指两个类型之间不存在任何隐式转换。在抗变关系下,类型之间无法互相赋值,除非显式进行类型转换。抗变关系保证了类型的严格一致性。
类型别名和接口
类型保护和类型区分
高级类型
- 交叉类型
- 联合类型
- 类型守卫
- 类型别名
- 条件类型
- 映射类型
- 可辨识联合
编译配置文件 tsconfig.json
声明全局变量、库、.d.ts
如何从任何.ts文件生成TypeScript定义文件?
可以使用tsc编译器从任何.ts文件生成TypeScript定义文件
tsc --declaration file1.ts
说说对TypeScript中命名空间与模块的理解?区别?
- 模块:与es6一样,任何包含顶级import或export的文件都被当成一个模块。如果一个文件不带有顶级的import或export声明,那么它的内容就视为全局可见的。
- 命名空间:定义了标识符的可见范围,主要目的就是
解决重名问题
declare,declare global是什么?
declare
是一个用于声明全局变量、全局类型或全局命名空间的关键字。它告诉编译器某个标识符已经存在,并且不需要在当前文件中进行具体实现。使用declare
关键字可以引入外部库、全局变量、或扩展 TypeScript 的类型定义。它与.d.ts
定义文件一起使用。
// 声明全局变量
declare var jQuery: (selector: string) => any;
// 声明全局类型
declare interface Person {
name: string;
age: number;
}
// 使用声明的全局变量和类型
const elem = jQuery("#myElement");
const person: Person = { name: "John", age: 25 };
declare global
是一种特殊的声明形式,用于在模块中声明全局变量或类型,并使其在整个项目中可用。
// 声明全局变量
declare global {
var globalVar: string;
}
// 使用全局变量
console.log(globalVar);