前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

# 类型兼容性

类型兼容性用于确定一个类型是否能赋值给其他类型,这看起来并没有什么太大用处,而实际上当我们了解了兼容性之后才会规避之后实际编程中的很多低级错误,笔者也是后来才意识到这一点的。

# 结构类型

TypeScript 里的类型兼容性是基于「结构类型」的,结构类型是一种只使用其成员来描述类型的方式,其基本规则是,如果 x 要兼容 y,那么 y 至少具有与 x 相同的属性。

我们做一个简单的实验,我们构建一个类 Person,然后声明一个接口 Dog,Dog 的属性 Person 都拥有,而且还多了其他属性,这种情况下 Dog 兼容了 Person。

class Person {
    constructor(public weight: number, public name: string, public born: string) {

    }
}

interface Dog {
    name: string
    weight: number
}

let x: Dog

x = new Person(120, 'cxk', '1996-12-12') // OK
@前端进阶之旅: 代码已经复制到剪贴板

但如果反过来,Person 并没有兼容 Dog,因为 Dog 的属性比 Person 要少了一个。

# 函数的类型兼容性

# 函数参数兼容性

函数类型的兼容性判断,要查看 x 是否能赋值给 y,首先看它们的参数列表。

x 的每个参数必须能在 y 里找到对应类型的参数,注意的是参数的名字相同与否无所谓,只看它们的类型。

这里,x 的每个参数在 y 中都能找到对应的参数,所以允许赋值:

let x = (a: number) => 0;
let y = (b: number, s: string) => 0;

y = x; // OK
x = y; // Error 不能将类型“(b: number, s: string) => number”分配给类型“(a: number) => number”。
@前端进阶之旅: 代码已经复制到剪贴板

那么当函数的参数中出现了可选参数或者 rest 参数时会怎么样呢?

let foo = (x: number, y: number) => {};
let bar = (x?: number, y?: number) => {};
let bas = (...args: number[]) => {};

foo = bar = bas;
bas = bar = foo;
@前端进阶之旅: 代码已经复制到剪贴板

如果你在 tsconfig.json 默认配置下上面的兼容性都是没问题的,但是在我们严格检测的环境下还是会报错的:

2019-06-25-15-58-11

原因就是可选类型的参数可能为 undefined,在这种情况下不能与 number 兼容。

当我们把 strictNullChecks 设置为 false 时上述代码是兼容的。

那么甚至他们的参数数量都不一致呢?

let foo = (x: number, y: number) => {};
let bar = (x?: number) => {};

foo = bar // ok
bar = foo //报错
@前端进阶之旅: 代码已经复制到剪贴板

我们看到参数较多的 foo 兼容了 bar。

# 枚举的类型兼容性

枚举与数字类型相互兼容:

enum Status {
  Ready,
  Waiting
}

let status = Status.Ready;
let num = 0;

status = num;
num = status;
fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏