在接触 TS 的过程中,时常能看到使用declare关键字来进行声明,而它基本都是出现在.d.ts文件中。你是否好奇过,使用declare关键字到底有什么作用?它与不使用declare关键字的声明又有何不同?本文与你一同探索declare的奥秘,讲述如何写好一个声明文件 (.d.ts文件),需要小伙伴们拥有一定的typescript基础。如果阅读本文过程中遇到不了解的知识点,可查阅我之前的基础篇的文章。 [toc] 一、Declaration Reference 声明指南我们先来了解到如何根据API文档和用法示例来编写相关的声明。这部分内容十分简单,基本看一遍过去就ok了。 1. 对象和属性我们通常使用命名空间来声明对象。 文档: 全局变量myLib,它有一个greet方法来创建问候语,一个numberOfGreetings属性来记录创建的问候语的数量。 示例: 123let greeting = myLib.greet("hello, cc!");console.log(greeting);let count = myLib.numberOfGreetin ...
上一篇介绍namespace多文件拆分的内容时,用到了一个三斜杠指令/// <reference path="xxx" />。这组指令有多个,其作用分别有所不同。有些同学还不是很了解这个语法,因而本文专门来介绍相关指令。 〇、注意事项三斜杠指令是包含一个XML单标签的单行三斜杠注释,注释的内容可被编译器识别,用来指示编译器在编译的过程中包含其它文件,或者用作规定文件输出顺序的方法。使用三斜杠指令时需要注意:只有出现在文件的开头才有效,否则将被当作没有特殊意义的普通注释。这意味着,在三斜杠指令之前,只能有单行或多行注释的存在,当然也可以有其它的三斜杠指令,而不能有其它的语句或者声明。 一、/// <reference path="..." />这是最常用的指令了,用来声明文件之间的依赖关系。 1. 预处理输入文件编译器将所有的三斜杠指令通过预处理传递输入文件的方式来解析,在此过程中,其它的文件会被添加到编译中。这个过程会从一系列根文件,即通过命令行或者tsconfig.json中指定的文件,按照指定的顺序开始开始。在文件被添 ...
在TypeScript 1.5之前的版本,有着内部模块Internal modules(使用module { }的形式来声明) 和外部模块External modules的概念。而从 1.5 版本开始,这两个概念的命名发生了变化。原本的Internal modules更改为Namespaces(命名空间),声明方式也相应替换为了namespace { },而External modules则更改为我们现在熟知的模块Modules。使用命名空间,可以自主定义对外可见/不可见的类型或值,能够极大地避免全局命名冲突的问题。我们使用export关键字来对外暴露相应的类型 / 值。 一、以官方提供的 Validators为例体验Namespaces123456789101112131415161718192021222324252627282930313233343536373839namespace Validation { // 通过export暴露的类型/值,可在namespaace外部访问 // 暴露一个interface,其包含一个 ...
JSX ,作为一种可嵌入的类 XML语法,玩过react的同学想必不会陌生。TypeScript支持嵌入和类型检查,并且可以直接将JSX编译为JavaScript。本文就TypeScript中的 JSX,即TSX的用法进行简要介绍。主要资料来源于官方文档,加入了少许自己的理解。 一、基础用法在 TS 中使用JSX之前,需要做两个准备: 将相关文件的拓展名更改为 .tsx; 启用jsx选项。 TS 附带了三种 jsx模式: preserve:将JSX保留为输出的一部分,且输出文件的拓展名为.jsx; react:由React.createElement来处理,使用前不需要经过JSX转换,输出文件的拓展名为.js; react-native:将JSX保留为输出的一部分,输出文件的拓展名为.js。 此外,一般还有 react-jsx、react-jsxdev等模式,此处不作介绍。我们可以在命令行或配置文件里来启用选择模式,例如,在tsconfig.json里做如下配置: 12345678{ "compilerOptions": { &q ...
枚举通过关键字 enum 来声明,会同时得到一个类型和一个同名的值,该值为一组命名了的常量。TS提供了基于数字和基于字符串的枚举,当然,这本该是基础篇的内容… 一、数字枚举我们使用关键字 enum 来声明一个枚举。当我们不给初值时,就会自动初始化,值依次从 0 开始递增。 12345678910111213enum Direction { Up, Down, Left, Right,}/*Direction.Up = 0Direction.Down = 1Direction.Left = 2Direction.Right = 3*/ 如果我们初始化了某属性的数值,紧随其后的其它属性的数值则会根据 步长为1 的递增/递减 自动推算。 12345678910111213enum Direction { Up = 1, Down, Left, Right,}/*Direction.Up = 1Direction.Down = 2Direction.Left = 3Direction.Right = 4*/ 枚举的使用也很简单。我们知道, ...
装饰器可以为类提供附加功能。在JS中,装饰器仍是第 2 阶段的提案,而在TS中,可作为一项实验性功能来使用,增强类的功能。 〇、启用装饰器由于装饰器是一项实验性功能,因此需要在命令行 或 tsconfig.json配置文件中启用。 1. 命令行启用在执行编译命令时 加入 --experimentalDecorators: 1npx tsc --target ES5 --experimentalDecorators 2. 在tsconfig.json中启用只需要修改配置文件即可: 123456{ "compilerOptions": { "target": "ES5", "experimentalDecorators": true }} 一、装饰器装饰器是一个函数,可以被附加到类的声明、方法、存取器、属性甚至是参数上,从而提供附加功能。装饰器的形式为 @ func*,其中 func 是一个函数。例如,我们给出一个 @sealed 装饰器,则应该有相应的 ...
TS 提供了许多实用的全局内置类型,可以极大地方便我们的操作。 1. Partial<Type> 可选类型接口通过Partial<T>可以通过将传入的类型的所有属性变为可选属性,从而得到一个新的类型。 123456789101112interface Person { name: string; age: number;}type PartialPerson = Partial<Person>;/*PartialPerson 为 { name?: string, age?: number}*/ 2. Required<Type> 必需类型接口与 Partial 相反,Required<T> 把传入的类型T的所有属性都变为必需的,得到一个新的类型。 123456789101112interface Person { name?: string; age?: number;}type RequiredPerson = Required<Person> ...
Typescript 系列 基础篇 (六) 模块化入门篇TS模块化是建立在JS模块化的基础上,与JS中的写法有许多的不同之处。TS极大地支持了主流的ESM和CommomJs,也对其他的模块化方案有所兼容。 一、ES 模块化语法1. export 导出TS支持ES模块化方案,写法和JS中一致。 12345678910111213// ModuleA.tsexport var a = 1;export const b = function () { // ...};export let c = () => { // ...};// 设置默认导出项,仅TS中可导出interface、type等export default interface Person { name: string; age: number;} 2. import 导入 使用import加载其它模块,和JS中一致,可以使用 as 重命名。 123// main.tsimport { a, b, c as RenamedC } f ...
TypeScript 系列 基础篇(五) Classes 类类 在 JavaScript 中出现于 ES2015 版本,TS对 类 进行了全面支持,还加入了一些其它语法来增强类的表达能力,本文将详细聊一聊TS中的类的知识,你知道的和不知道的,这里都有。 一、类的成员1. 属性字段 (Fields)字段声明会为类添加创建一个公共的可写的实例属性。我们可以为字段添加类型注释,如果不添加,就会是 any 类型,当然这是我们不希望发生的。 12345class Person { name: string; age: number; gender; // gender为 any 类型} 字段声明时可以赋初值,其类型会被 TS 自动推论,在实例化时会自动执行值的初始化。 123456789class Person { name = "cc"; // name为string类型 age = 18; // age 为 string 类型 gender: 1 | 2 = 2; // 如果不注释类型,则gender会被推论为number ...
TypeScript 系列基础篇(四) 类型操纵定义一个类型,我们通常使用interface和 type关键字来进行规定,有时候也会直接使用字面量类型,这些过程足以应付大部分场景。但是有些时候,我们希望掌握从已经存在的值或者类型中提取或派生出新的类型的技巧,这就是我们今天要来了解的Type Manipulation 类型操纵。相信我,掌握这些技巧后,你也能被各种类型玩出百般花样。 一、使用 keyof 操作符使用 keyof 操作符,可以获取一个 对象类型 的属性名 (字符串或者数值),并将其组合成一个联合类型。注意得到的是一个类型,因此应使用type关键字,而不能使用var, let, const等声明值变量的关键字。 一般情况下,keyof操作会得到字面量联合类型; 123456789// Person类型有三个属性,属性名分别为"name","age",100interface Person { name: string; age: number; 100: string[];}// 对Person类型使用ke ...