TS 初级面试题(基础类型、type与interface的区别)

3,589 阅读4分钟

typescript 基础类型

  • 基础静态类型
// number
const count:number = 123;  //显示注解一个number类型
const count1 = 12; // 不显示注解,ts会自动推导出类型

//string
const str:string = '你好'
const str1 = '你好'

// boolean
const status:string = false
const status1 = true

// null
const value:null = null
const value1:null = undefined;// null == undefined

// undefined
const value:undefined = undefined
const value:undefined = null

// void (无效),一般用在函数上,告诉别人这个函数没有返回值
function fn():void{}
function fn():void{ return null}
function fn():void{ return undefined}

  • 对象静态类型
// 对象
const test:{
    name:string,
    age:number
} = {
    name:'comix',
    age:19
}

// 数组

const testArry :string[] = ['123','232']

// 类

class Person{}
const test:Person = new Person()

// 函数

const test:() => string = () => {
   return 'xiao'
}
  • 联合类型 用|表示,满足其中一个类型就可以
const statusTest:string | number = "你好"
  • 交叉类型 用&表示,表示所有类型都必须存在
  • 泛型 针对不确定的类型使用,<T>
function test<T>(a:T,b:T){
  console.log(a,b)
}
test<any>(1,'你好')

// public为类的公共属性,在类的内部或外部,都可以访问该类的属性和方法,默认定义的属性及方法都是public 
class Person {
   name ="你好"
   public age = 12
}
const res = new Person()
console.log(res.name,res.age) // 你好 12

//private为类的私有属性,只有在当前类里面才可访问,即使是extends继承,也无法访问(子类无法访问)
class Person {
    private name = "你好"
    private age = 122
}
const res = new Person()
console.log(res.name,res.age) // 报错,无法访问

// protected为类的保护属性,只有在当前类和子类可以访问
class Person{
   protected name = "你好"
   protected age = 12
}
const res = new Person()
console.log(res.name,res.age) // 报错
class Scholl extends Person {
    getData(){
       return this.name + this.age
    }
}
const temp = new Scholl()
console.log(temp.getData()) // 你好 12。可以正常访问父类的属性

const与readonly的区别?

  • const用于变量,readonly用于属性
  • const在运行时检查,readonly在编译时检查
  • 使用const变量保存的数组,可以使用push,pop等方法。如果使用ReadonlyArray<number>声明的数组不能使用push,pop等方法

type(类型别名)与interface(接口) 的区别

定义:类型别名:用一个类型,使用type创建类型别名,可以用来表示基本类型、对象类型、联合类型、元祖和交集。

接口:命名数据结构的另一种方式,interface仅限于描述对象类型

相同点:
  • 都可以描述一个对象或函数
interface User {
 name: string
 age: number
}
 
interface SetUser {
 (name: string, age: number): void;
}
type User = {
 name: string
 age: number
};
 
type SetUser = (name: string, age: number): void;
  • 都可以继承

接口可以扩展类型别名,类型别名也可以扩展接口

接口的扩展就是继承,通过extends实现。类型别名的扩展就是交叉类型,通过&实现

// 接口扩展接口
interface PointX{
   x:number
}
interface Point extends PointX {
  y:number
}

// 类型别名扩展类型别名
type PointX = {
  x:number
}
type Point = PointX & {
   y:number
}
// interface继承type
type Person {
  z:string
}
interface Point extends Person{
  z1:string
}
// type 继承interface
interface Person{
  name:string
}
type Student = Perosn & {stuNo:number}
不同点:
  • 接口只能声明对象,类型别名的右边可以是任何类型(包括对象),包括基本类型、元祖、类型表达式(& 或 | 等类型运算符)
  • 扩展时表现不同
// interface 
interface Point1 {
  x:number
}
interface Point extends Point1 {
  x:string // Interface 'Point' incorrectly extends interface 'Point1'
}
type Point1 = {
   x:number
}
type Point2 = {
   x:string
}
type Point = Point1 & Point2 //这时的Point是一个'number & string' 类型,也就是never

总结:接口继承同名属性不满足定义会报错,而相交类型就是简单的合并

  • 多次定义时表现不同(声明合并)
    • interface可以定义多次,多次的声明会合并
    • 类型别名(type)不可以定义多次,会报错

interface Point {
  x:number
}
interface Point {
   y:number
}
const point:Point = {x:1,y:1} // 正确

type Point = {
  x:number  // Duplicate identifier 'A'
}
type Point = {
  y:number  // Duplicate identifier 'A'
}
  • 计算属性

type 能使用in关键字生成映射类型,但interface不行

type Keys = 'firstname' | 'lastname'
type DudeType = {
  [key in keys] :string
}
const test:DudeType = {
  firstname:'tt',
  lastname:'yy'
}

接口和抽象类之间的区别

type多态性

如何解决typescript没有重载的问题

声明合并总结

请描述下:不变,协方差, 逆变,双方差

如何判断A是B的子类型

对于参数请回答: 什么时候数组是数组的一个子类型? 什么时候一个形状A是另一个形状B的一个子类型?

判断函数

什么是类型拓展

infer的使用

.d.ts的作用