前端面试题--TypeScript

1.TypeScript是什么,与JavaScript的关系

ts是js的超集,是js更严格的严格版本。ts添加了静态类型系统和编译时的一些特性。

主要的联系和区别:

  1. 类型系统。js是动态类型的语言,不需要在代码中声明变量的类型;ts使用了静态类型系统,在代码中必须明确的声明所有变量的类型,这有利于发现错误,可使大型代码库更容易维护。
  2. 编译。ts需要经过编译才可以在浏览器或node中运行,它需要先转换成js代码在运行。
  3. 可扩展性。因为ts是js的超集,所以可以将现有的js项目迁移到ts,不需要重写整个代码。
  4. 类型安全。静态类型系统,可以使ts代码在编译阶段就可以发现错误,不需要等到运行时才发现。
  5. 高级类型。ts支持泛型、接口等,这可以使代码更加可维护。
2. TypeScript 中有哪些内置类型?
  1. any:表示任意类型,可以存储任何值。
  2. number:表示数值类型,包括整数和浮点数。
  3. string:表示字符串类型。
  4. boolean:表示布尔类型,只有两个值:true 和 false。
  5. void:表示无类型,通常用于表示没有返回值的函数。
  6. null 和 undefined:表示特殊的值类型。
  7. symbol:表示唯一的标识符类型。
  8. tuple:表示固定数量的元素集合,用于表示已知数量的不同类型的数据。
  9. enum:表示枚举类型,用于定义一组命名的常量值。
  10. class:表示类类型,用于定义对象和构造函数。
  11. interface:表示接口类型,用于定义对象的形状和行为。
  12. type alias:表示类型别名,用于为复杂类型定义简化的名称。
  13. function type:表示函数类型,用于定义函数参数和返回值的类型。
  14. generic type:表示泛型类型,用于定义可重用的组件,可以处理多种数据类型。
3. TypeScript中的接口是什么,如何使用?

接口在ts中用来定义对象的结构及属性的类型。使用interface定义

//定义接口
interface Person {
    name string;
    age number;
    eat(food string):string
}

//使用接口
class Student implements Person {
    name:string;
    age:number;
    
    constructor(name:string,age:number){
        this.name = name;
        this.age = age;
    }

    eat(food:string){
        return food;
    }    
    
}
4.TypeScript中如何定义和使用泛型?

泛型可以用来在定义函数、接口、类时不提前指定具体的类型,而是在使用的时候为其指定类型。

泛型有类型推断,编译器会根据传入的参数自动确定T的类型

function fn  (x:T,y:T): T{
    return x + y;
}
fn(1,2)
5.TypeScript中any和unknown类型的区别?

any类型表示任何值都可以,它会关闭编译器的类型检查,使用any类型,变量可以被赋值为任意类型。

unknown表示一个未知的值,比any更严格。使用unknown时不可以直接访问其内部属性,需要进行类型断言。这样可以增加类型安全性。

const x:unknown = new Person();
// x.name; 这种方法是错误的

const y =  x;  //类型断言
x.name;  
6.TypeScript中,枚举类型如何使用?

枚举类型:用于表示一组命名的常量值。

//定义枚举
enum Color {
    Red = 1,
    Blue = 2,
    Green = 3
}

let bg:Color;
bg = Color.Red;

//获取枚举类型的key值
Object.keys(Color) 
Color[0]
7.在TypeScript中,什么是类型推断?

类型推断是编译器根据变量、函数的参数和返回值的实际使用情况推断出它们的类型。

8.在TypeScript中,什么是装饰器? 

装饰器是一种特殊类型的声明,可以被附加到类声明、方法、属性或参数上。

如果要使用装饰器,需要在tsconfig.json中配置:

"compilerOptions": {
    "experimentalDecorators": true
}

  * 类装饰器(无法传参)

function fn1(target:any){
    target.prototype.userName = '1'  //添加属性
}

@fn1  //相当于fn1(Person)
class Person {}

const p1 = new Person();
console.log(p1.userName);  //1

* 装饰器工厂

function fn2(options:any){
    return function (target:any){
        target.prototype.name = options.name
    }
}

@fn2({
    name:'jjjj'
})
class Person1 {}

const p2 = new Person1()
console.log(p2.name);

如果有多个装饰器,会从上到下执行每个装饰器工厂,拿到所有真正的装饰器,然后从下到上执行所有的装饰器。

* 属性装饰器

function fn3(target:any,attr:any){
    console.log(target,attr);  //attr = undefined

    target[attr] = 'dd'
    console.log(target,attr);  //attr = dd  
}
class Person2 {
    @fn3
    name:string
}

* 方法装饰器

9.TypeScript中类型断言是什么?

 类型断言类似于Java语言中的类型转换。类型断言对运行时没有影响,仅对编译器使用。

10. TypeScript中type和interface接口有什么区别?
  1. 接口只能定义对象类型,包括类、对象和对象的形状;类型别名可以表示任何类型。
  2. 接口可以被其他接口继承;类型别名不能直接继承,但可以通过交叉类型来组合多个类型,或者使用泛型来创建可重用的类型。
  3. 在不同地方声明相同名称的接口,会自动合并为一个接口;类型别名不可以重名。
11.TypeScript中const和readonly的区别是什么?
  1. const用来声明常量,一旦赋值就不可以被修改;readonly用来声明只读属性,该属性在初始化后就不可以被修改 。
  2. const声明的常量必须被初始化,类型在初始化时被固定,在声明后不可以修改;readonly可以在初始化时指定类型,但是可以在对象方法中被修改。
  3. const声明的变量有块级作用域;readonly声明的属性是对象的一部分,可以在对象方法中被访问。
  4. const在运行时检查;readonly在编译时检查。
12.TypeScript的tsconfig.json中有哪些配置信息? 
  1. compilerOptions:编译器选项,如语言版本、目标JavaScript版本等;
  2. include:指定需要编译的文件路径或文件夹路径;
  3. exclude:指定不需要编译的文件路径或文件夹路径;
  4. files:指定需要编译的文件列表;
  5. extends:指定继承自另一个tsconfig.json文件;
  6. complieOnSave/buildOnSave:指定是否在保存时编译文件;
  7. target:编译目标JavaScript版本,如“ES5”、“ES6”;
  8. module:指定模块系统,可以是“CommonJS”、“AMD”等;
  9. outDir:编译输出的目录;
  10. strict:是否开启严格类型检查;  .......
 13.keyof和typeof关键字如何使用?

keyof:用于某个类型的所有属性名组成的联合类型,主要用在接口、对象或类的属性上。

interface Person {
    name:string;
    age:number;
}

type Keys = keyof Person; // 'name'|'age'

typeof:通常与类型联合使用,用来表示一个值的类型。用于获取一个值的类型。

14.TypeScript中的Declare关键字有什么作用? 

declare用于声明一个变量、函数、类、模块等,但不为其分配具体的实现。通常用于告诉ts编译器某个变量、函数存在于代码之外,可能在一个外部的库中,或运行环境中。通过使用declare,可以在ts代码中安全的使用这些外部的实体,而不会引发编译错误。

15. TypeScript 模块的加载机制?

TypeScript的模块加载机制基于nodejs的模块加载机制,采用相对路径和绝对路径来查找。

ts会按照一定的顺序在文件系统路径中查找,如果找不到模块,ts会尝试在全局安装的模块中查找该模块,最后找不到,会抛出错误。

 16.如何理解TypeScript中的类型兼容性?

ts中的类型兼容性是指一个类型是否可以被赋值给另一个类型。类型兼容性是基于结构类型系统来判断的,如果一个类型结构上包含另一个类型的所有信息,那这个类型就可以赋值给另一个类型。

interface Person {
    name:string;
    age:number;
}

class Student implements Person {
    name = 'a';
    age = 18;
    say:():void => {}
}

const s1:Person = {name:'b',age:10}
cinst s2:Person = new Student()
//虽然Student比Person属性更多,但是Student中包含了Person中的所有属性。所以Student兼容于Person。
17.TypeScript 中对象展开会有什么副作用吗?
  1. 深拷贝问题,对象展开是浅拷贝,如果对象的属性值为对象或数组,展开运算符只会复制顶层的引用地址,如果修改可能会修改原对象。
  2. 类型推断,如果一个对象属性没有明确的类型注解,ts可能无法推断出该属性的类型,这就需要额外的类型注解或类型断言。
  3. 性能开销,对于大型的对象,对象展开可能会导致额外的性能开销。
  4. 可读性和可维护性,可能会降低代码的可读性和可维护性。
18.Omit 类型有什么作用?怎么使用? 

Omit是一个泛型类型,用于从一个给定的类型中排除某些属性,并返回一个新的类型。

type Person = {name:string; age:number; gender:string}
type WithoutGender = Omit  //{name:string; age:number; }

......持续更新中

你可能感兴趣的:(前端,typescript,javascript)