本文主要通过一些实际的代码示例,来帮助大家理解什么是类型扩展,本文主要内容如下:

  1. 什么是类型扩展
  2. 代码示例
  3. 总结

什么是类型扩展?

TypeScript 需要从你指定的单一值中决定一组可能的值,这个过程成为类型扩展

代码示例

interface Vector { x: number; y: number; z: number; }

function getComponent(vector: Vector, axis: keyof Vector) { return vector[axis]; }

当你使用它时,TypeScript会提示一个错误.

//~类型string的参数不能赋值给类型 "x"|"y"|"z"的参数

报错的原因在于,x被推断为string,而getComponent的第二个参数则是期望得到一个更加具体的单位类型

这就是类型扩展在起作用,所以导致这里产生了一个错误。

x被推断为string,因为typescript允许这样的代码:

let x = 'x';x = 'a'; x = 'b';

typescript试图在特殊性和灵活性之间找到平衡,一般的规则是,一个变量的类型不应该在它被声明后改变,所以string 比 string|Regexp或者string|string[]或者any更合理。

TypeScript给了一些方法控制类型扩展过程,其中一种就是const,如果你用const而不是let,var来声明变量,就会得到一个更窄的类型。

const x = "x"; //x的类型为"x",而不是string;

然而const对数组和对象来说仍然无效,因为在js中,对象自身不变的情况下,对象里面的属性是可以改变的。

比如:

const v = {x:1};

v的类型可以被推断到任意程度,最具体的为:{readonly x :1},一般化的是{x:number},再一般化的就是{[key:string]:number}或者object了。

对于对象来说,Typescript 的类型扩展算法会把对象中的每个元素当作是用let赋值了,所以,const v = {x:1}

的类型 就是 {x:number};

我们可以通过Typescript 提供的方法来覆盖Typescript 的默认行为。

  1. 提供一个明确的类型标注 const v:{x:1|3|5} = {x:1}
  2. 为类型检查器提供额外的上下文 通过传递值作为函数的参数
  3. 使用const断言 // const断言是纯粹的运行在类型空间的东西

    const v1 = {x:1,y:1};//类型为{x:number,y:number}

    const v2 = {x:1 as const,y:1};//类型为 {x:1,y:number}

    const v3 = {x:1,y:2} as const; //类型为 {x:readonly x :number,readonly y:number}

当你在一个值后面写as const的时候,TypeScript会把它推断成最窄的类型.

更鲜明的例子:

const a1 = [1,2,3];//类型为 number[]

const a2 = [1,2,3] as const;//类型为readonly [1,2,3]

总结

  • 了解TypeScript是如何通过扩展常量来推断类型的
  • 熟悉影响这种行为的方法:const , 上下文,和 as const注释。

《Effective TypeScript》条款21 - 类型扩展的更多相关文章

  1. Effective C++ -----条款21:必须返回对象时,别妄想返回其reference

    绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...

  2. 必须返回对象时,别妄想返回其reference 【Effective C++ 条款21】

    class Rational { public: Rational(, ) : n(numerator), d(denominator) { printf("Rational Constru ...

  3. TypeScript Type Compatibility(类型兼容)

    TypeScript中的类型兼容是基于结构归类的.在普通分类的相比之下,结构归类是一种纯粹用于将其成员的类型进行关联的方法.思考下面的代码: interface Named { name: strin ...

  4. More Effective C++ 条款0,1

    More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...

  5. Util应用程序框架公共操作类(十):可空值类型扩展

    当你使用可空的值类型时,你会发现取值很不方便,比如Guid? obj,你要从obj中获取值,可以使用Value属性obj. Value,但obj可能为null,这时候就会抛出一个异常. 可空值类型提供 ...

  6. TypeScript Type Innference(类型推断)

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

  7. [More Effective C++]条款22有关返回值优化的验证结果

    (这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...

  8. TypeScript 之 基础类型、高级类型

    基础类型:https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html 高级类型:https ...

  9. TypeScript完全解读(26课时)_11.TypeScript完全解读-类型推论和兼容性

    11.TypeScript完全解读-类型推论和兼容性 在一些时候省略指令,ts会帮我们推断出省略的类型的地方适合的类型,通过学习ts的类型推论了解ts的推论规则 类型兼容性就是为了适应js灵活的特点, ...

  10. C# 用this修饰符为原始类型扩展方法

    特点:1.静态类 2.静态方法 3.第一个参数前加this 例如:public static List<T> ToList<T>(this string Json),就是为th ...

随机推荐

  1. vue3 'alex' is defined but never used

    解决方法 在package.json中的rules下加入 "no-unused-vars":"off" 即可

  2. 外部网关协议BGP

    不能全部使用RIP与OSPF的原因有二:互联网规模太大,自治系统间路由选择困难:自治系统间路由选择必须考虑有关策略. 在每一个自治系统中有两种不同功能的路由器,边界路由器和内部路由器. BGP四种报文 ...

  3. 服务之间的调用之RPC深入理解

    一:RPC RPC 即远程过程调用(Remote Procedure Call Protocol,简称RPC),像调用本地服务(方法)一样调用服务器的服务(方法).通常的实现有 XML-RPC , J ...

  4. oeasy教您玩转vim - 6 - # 保存修改

    另存与保存 回忆上节课内容 我们上次进入了插入模式 从正常模式,按<kbd>i</kbd>,进插入模式 从插入模式,按<kbd>ctrl</kbd>+& ...

  5. oeasy 教您玩转 linux 010400 总结 summary

    ###### 上一部分我们都讲了什么?*   各种gui*   qt和gdk两个开源工具跨平台开发库*   发行版和gui之间的关系###### 我们一起来回顾一下整个学习过程*   我们从零开始*  ...

  6. [oeasy]python0027_整合程序_延迟输出时间_整合两个py程序

    ​ 整合程序 回忆上次内容 通过搜索发现 time中有函数可以延迟 time.sleep(1) 还可以让程序无限循环 while True: 现在需要两个程序的整合 循环延迟输出 时间输出 ​ 编辑 ...

  7. 题解:AT_abc359_c [ABC359C] Tile Distance 2

    背景 去中考了,比赛没打,来补一下题. 分析 这道题让我想起了这道题(连题目名称都是连着的),不过显然要简单一些. 这道题显然要推一些式子.我们发现,和上面提到的那道题目一样,沿着对角线走台阶,纵坐标 ...

  8. 适用于 .NET 的现代化、流畅、可测试的HTTP客户端库

    前言 今天大姚给大家分享一个.NET开源(MIT License).免费.现代化.流畅.可测试.可移植的URL构建器和HTTP客户端库:Flurl. 项目介绍 Flurl是一个集现代性.流畅性.异步性 ...

  9. 【MybatisPlus】再补充内容

    2021年7月21日 14点05分 看尚硅谷新讲的尚医通,这个MP的文档多了新东西: 依赖版本: springBoot版本  2.2.1.RELEASE <dependencies> &l ...

  10. 【Shiro】05 自定义Realm认证实现

    [前提情要] Shiro默认使用自带的IniRealm,IniRealm从ini配置文件中读取用户的信息, 大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm. 根接口:Realm ...