类型推断

类型推断,指不需要指定变量类型或者函数的返回值类型,TypeScript可以根据一些简单的规则推断其类型。

类型推断是有方向的,要注意区分从左向右和从右向左两种推断的不同引用。

基础类型推断

基础类型推断发送在初始化变量、设置默认参数和决定函数返回值时

let num = 3;        // 推断为number类型
let str = 'string';  // 推断为string类型
let bool = true;    // 推断为boolean类型
let u = undefined;  // 推断为boolean类型
let n = null;       // 推断为null类型num = 'xman';   // Type '"xman"' is not assignable to type 'number'.
str = 18;       // Type '18' is not assignable to type 'string'.
bool = '60'     // Type '"60"' is not assignable to type 'boolean'.
u = 1;          // Type '1' is not assignable to type 'undefined'.
n = true;       // Type 'true' is not assignable to type 'null'.

注意:在TypeScript中,使用const和let声明的类型,默认推断出的类型是不同的,如:

{let str = 'this is string';   // 推断为string类型let num = 1;          // 推断为number类型let bool = true;      // 推断为boolean类型
}
{const str = 'this is string';   // 字符串字面量类型'this is string'const num = 1;            // 数字字面量类型  1const bool = true;       // 布尔字面量类型 true
}

解释: 当我们将一个字面量类型声明为常量,我们就不能再对其进行修改了,因此将其类型推断为赋值的字面量类型,是一种比较合理的设计。
而使用 let 声明的字面量类型,因为我们还拥有将其修改为该类型其他字面量的权利,因此TypeScript将其类型转换为了赋值字面量类型的父类型,这种设计也是符合编程预期的。

我们将 TypeScript 的字面量子类型转换为父类型的这种设计称之为 "literal widening",也就是字面量类型的拓宽。

如果定义的时候没有赋值, 不管之后有没有赋值,都会被推断为 any 类型 而完全不被类型检查:

let a;    // 推断为any类型
a = 'hello';
a = false;
a = 100;
a = undefined;
a = null;
a = {};

最佳通用类型推断

最佳通用类型,顾名思义,就是对于某些表达式的最合适的通用类型

计算通用类型的算法会考虑所有的候选类型,并给出一个兼容所有候选类型的类型。

let a = ['xman', 18, true];  // a被推断为(string|number|boolen)[] 联合类型
a[3] = 2;       // Type 'null' is not assignable to type 'string | number | boolean'.

以上,数组里包含多个类型string、number、boolean, TypeScript就推断出兼容所有类型的通用类型(string | number | boolen)[] 联合类型

上下文类型推断

TypeScript类型推论也可能按照相反的方向进行。 这被叫做“按上下文归类”。按上下文归类会发生在表达式的类型与所处的位置相关时
上下文归类会在很多情况下使用到。 通常包含函数的参数,赋值表达式的右边,类型断言,对象成员和数组字面量和返回值语句。 上下文类型推断则是从左向右的类型推断。
上下文类型还充当最佳公共类型中的候选类型。

  1. 根据参数的类型,推端出返回值的类型
// 根据参数的类型,推端出返回值的类型也是number
function add (x: number, y: number) {return x + y;
}let sum = add (1, 2);   // 推断出sum的类型也是number
sum = '123';    // Type '"123"' is not assignable to type 'number'.// y 被推断为number | undefined
function add1 (x: number, y = 2) {return x + y;
}
add1(1, '2');  // Argument of type '"2"' is not assignable to parameter of type 'number | undefined'.
  1. 函数参数类型/返回值通过赋值来推断
type Adder = (x: number, y: number) => number;
let add: Adder = (x, y) => x + y;add('1', 2);    // Argument of type '"1"' is not assignable to parameter of type 'number'.
let sum = add(1, 2);    // 推断出sum的类型也是number
sum = '123';   // Type '"123"' is not assignable to type 'number'.

以上代码中, add的类型是Adder,它能让add的参数x, y是number类型, 返回值也推断为number类型。
以上是一个从左向右流动类型的示例。
如果你创建一个函数,并且函数参数为一个回调函数,相同的赋值规则也适用于它。从 argument 至 parameter 只是变量赋值的另一种形式。

type Adder = (x: number, y: number) => number;
function fn(add: Adder) {return add(1, 2);
}
fn((x, y) => {x = 'hello';      // Type '"hello"' is not assignable to type 'number'.  return x + y;
})
  1. 对象成员
    对于对象字面量
const obj = {name: 'xman',age: 18
};
// obj类型被推断为 { name: string; age: number; }
obj.name = false;       // Type 'false' is not assignable to type 'string'.

解构中:

const obj = {name: 'xman',age: 18
};let { name } = obj;
name = true;    // Type 'true' is not assignable to type 'number'.const a = ['xman', 18];
let [x, y] = a;     // 此时x, y都被推断为'string | number'
y = false;    // Type 'false' is not assignable to type 'string | number'.
  1. 类型断言
interface IAdd {(x: number, y: number): number;
}
const add = function (x, y) {return x + y;
} as IAdd;add(1, 2);   // Argument of type '"2"' is not assignable to parameter of type 'number'.

以上代码中我们给匿名函数指定了类型上下文IAdd, 从而推断出参数x, y类型都是number类型。

最后, 如有错误,欢迎各位大佬指点!感谢!

参考资料

https://www.typescriptlang.org/docs/handbook/type-inference.html#handbook-content

https://jkchao.github.io/typescript-book-chinese/typings/typeInference.html

TypeScript基础之类型推断相关推荐

  1. TypeScript Type Innference(类型推断)

    在这一节,我们将介绍TypeScript中的类型推断.我们将会讨论类型推断需要在何处用到以及如何推断. 基础 在TypeScript中,在几个没有明确指定类型注释的地方将会使用类型推断来提供类型信息. ...

  2. TypeScript 基础类型+函数+接口+类

    1.简介: TypeScript 是 JavaScript 的一个超集.由微软开发的自由和开源的编程语言.设计目标是开发大型应用.是一种面向对象的编程语言,遵循强类型 javascript与types ...

  3. TypeScript 基础 建议收藏!

    1.TypeScript 简介 1.1.什么是 TypeScript TypeScript 不是一门全新的语言,TypeScript 是 JavaScript 的超集,它对 JavaScript 进行 ...

  4. typescript利用接口类型声明变量_TypeScript入门指南(基础篇)

       戳蓝字「前端技术优选」关注我们哦! 作者:慕晨同学 原文地址:https://github.com/USTB-musion/fee-skills/issues/19 写在前面 ts是拥有类型系统 ...

  5. TypeScript基础入门 - 接口 - 可索引的类型

    转载地址 TypeScript基础入门 - 接口 - 可索引的类型 项目实践仓库 https://github.com/durban89/typescript_demo.git tag: 1.0.11 ...

  6. TypeScript 基础类型 1

    TypeScript 基础类型 自本节起,我们将开始接触 TypeScript 的类型系统,这也是 TypeScript 最为核心的部分. 本节介绍 TypeScript 中一些基础类型,有些特殊类型 ...

  7. TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions)

    2019独角兽企业重金招聘Python工程师标准>>> 转发 TypeScript基础入门之高级类型的可辨识联合(Discriminated Unions) 高级类型 可辨识联合(D ...

  8. TypeScript基础入门 - 函数 - 简介

    2019独角兽企业重金招聘Python工程师标准>>> 转载 TypeScript基础入门 - 函数 - 简介 项目实践仓库 https://github.com/durban89/ ...

  9. TypeScript基础+进阶

    ----------------------------------------------------------------------------- ts  typescript 是 js的超集 ...

  10. TypeScript基础教程

    一.TypeScript简介 1. 特性 Typescript是以JavaScript为基础构建语言 一个JavaScript的超集 不能被JS解析器直接执行 扩展了JS,并添加了类型 TS.ES6. ...

最新文章

  1. 结构体中string类型成员
  2. git 恢复被覆盖本地提交内容
  3. Coursera公开课笔记: 斯坦福大学机器学习第十一课“机器学习系统设计(Machine learning system design)”
  4. java map判断是否有键_检查Java HashMap中是否存在给定键
  5. jQuery杂项进阶(四)
  6. Bootstrap 3: 使用注意box-sizing细节及解决方法
  7. Firefox 使用 Chrome 浏览器的 PDF 和 Flash 插件
  8. abstract、virtual、override 和 new
  9. MySQL数据表类型及文件结构
  10. windows游戏编程 (一) 了解WinMain函数,创建一个信息框
  11. 中国行政区域边界坐标(google)
  12. 小米5splus(高配版/全网通)线刷兼救砖_解账户锁_纯净刷机包_教程
  13. 虾皮台湾店标价是用台币吗?要如何定价?
  14. Unity学习笔记 - API
  15. manjaro pacman,yaourt命令
  16. opencv:图像的放大与缩小
  17. MySQL8.0 Optimizer Hints
  18. 【华为OD机试真题 JAVA】九宫格按键输入
  19. 谷歌上面滚动条有时候不管用_可以用的谷歌图片搜图软件
  20. ROM、PROM、EPROM、EEPROM、FLASH ROM

热门文章

  1. 网站备案必须有服务器吗,域名备案必须有服务器吗
  2. 手写vue3源码——reactive, effect ,scheduler, stop 等
  3. 为什么有了FineBI后还会有FineReport?这两者的区别真的很大
  4. 银行叫警察抓人?逾期未还后果严重可能成真!
  5. 场景一:刮刮卡,大转盘等抽奖算法
  6. 肝了一天一夜 吐血整理的超级实用的Web前端面试题总结
  7. matlab模拟出现较大误差是什么原因,关于使用lsqcurvefit拟合曲线出现误差巨大的问题...
  8. infer的用法_infer使用的浅谈简析
  9. 瑞芯微(RKDocs)平台技术开发资料汇总(rk3188,rk3066,RK3128,rk3288)
  10. SSH-简单登陆业务详解,从环境部署到代码编写