TypeScript
2018-11-05 14:18:35 0 举报
AI智能生成
TypeScript语法
作者其他创作
大纲/内容
英文官网
有少量错误,请参照英文版
本文结构来自于中文官网
中文官网
语言规范
GitHub
官网official site
鸭式辨型法duck typing
或 结构性子类型化structural subtyping
它有时被称做
另一个解读:“不把类型检查带到runtime”
对值所具有的结构进行类型检查。
核心原则core principles
标识符可以包括下划线,字符和数字。标识符不能以数字开头
标识符不能是关键字
标识符必须是唯一的
标识符是区分大小写
标识符
语句结束符号分号是可选的
分隔符
单行 //
多行 /* */
注释
关键字
基础
boolean
浮点数
number
\" \"
普通字符串
反引号是标准键盘数字键1左边的波浪号键
类似于C#的格式化字符串
示例
` ${ }`
模板字符串
string
数组 []
多维数组[][]
泛型数组 Array<T>
泛型只读数组 ReadonlyArray<T>
sort 与c#用法相同
数组的排序
注意Array没有remove方法,使用splice替代
注意splice的第二个参数,一般情况下需要手动填1,否则意味着删除之后所有元素
数组的删除
Array 数组
一个已知元素数量和类型的数组,各元素的类型不必相同
当访问一个越界的元素,会使用联合类型替代
Tuple和struct的区别是什么?
Tuple 元组
enum 示例
默认从0开始编号
enum
这意味着any数据可以调用任何属性/方法而编译不报错(哪怕这些属性/方法不存在),直到运行时才会报错
引入这个类型的原因就是为了打破自己的核心原则么?
动态类型,会跳过编译器检查
Any可以调用任意实例的方法
Object只能调用Object的方法
与Object的区别
any
用于函数表示没有返回值
可以被赋值 null 和 undefined
void
默认情况下null和undefined是所有类型的子类型
如果指定了strictNullChecks,null只能赋值给null类型
null
如果指定了strictNullChecks,undefined只能赋值给undefined类型
undefined
例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型
never类型表示的是那些永不存在的值的类型
never类型是任何类型的子类型,也可以赋值给任何类型
只有never才能赋值给never,any不可以赋值给never
never
object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型
Object
跳过编译,但不影响运行
<> 语法
as 语法
特例:当使用JSX时只能使用as
as与<>是等价的
类型断言
基础类型Basic Types
可以包含字母,数字,下划线 和 $
不能包含空格和特殊字符
不能以数字开头
遵循JS的命名规则
由于JQuery广泛运用,一般单独的$是指jQuery
ES3 曾建议将$开头的命名用于自动生成的代码
特殊的$
命名规则
请使用let替换var
详见js章节
作用域
var 声明
示例1 if 块
示例2 try catch 块
示例
不能在被声明之前读或写
但可以在被声明前获取它 (仅仅是写法上的)
词法作用域(或块作用域)
let 声明
注意内部值是可以修改的
类中如何定义常量?参见接口章节
不可用于类成员的修饰符
const 声明
不应修改的量仍然使用const
let VS const
做为变量使用的话用 const,若做为属性则使用readonly。
readonly vs const
对比
常规用法
交换
函数参数
剩余变量
忽略尾部变量
忽略部分变量
默认值
数组解构[]
强制类型
提取属性值
剩余变量(剩余对象?)
为什么要引入这个语法??
注意此处冒号后跟随的不是类型而是新变量名字
此处似乎无法强制类型
属性重命名
对象解构{}
简单情况
首先需要在默认值之前设置其格式
其次需要知道在解构属性上给予一个默认或可选的属性用来替换主初始化列表。
复杂情况
函数声明{}
要小心使用解构
避免在深层嵌套中解构
解构表达式要保持小而简单
注意
解构 Destructuring
展开创建了一份浅拷贝
将数组展开为另一个数组
注意展开顺序是从左到右的,如果右侧与左侧有相同的属性,会被右侧的属性覆盖
Enumerable properties 枚举属性
这个涉及到js里的prototype的概念,尚不理解
Ownership of properties
此句可简单理解为扩展对象会丢失方法
对象展开仅包含自身的直接属性和可枚举属性
将对象展开为另一个对象
暂不允许展开泛型函数上的类型参数
展开(Spread) ...
变量声明Variable Declarations
简单示例
这里shape翻译为“外形”似乎有点奇怪?
属性
可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值
好处1 对可能存在的属性进行预定义
比如故意将color属性名字拼写错误
好处2 可以捕获引用了不存在的属性时的错误
可选属性?
个人看法这个段落应归到“基本类型”中
只读属性
ReadonlyArray<T>
只读数组
检查对象是否存在任何“目标类型”不包含的属性
在JavaScript里,这样写是允许的(但不能正确赋值)
TypeScript会认为这段代码可能存在bug并报错
示例 拼写错误
可以避免拼写错误
方法1 断言
方法2 向接口中添加索引签名(推荐)
没理解为什么会绕过检查?
方法3 将对象赋值给另一个对象
如何绕开此限定
额外的属性检查
这里的用法与以上几种都不同
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
可以省略类型,让编辑器做类型推断
函数的参数名不需要与接口里定义的名字相匹配
这个用法的意义是什么?提供比类的灵活性更高的一种用法?
函数类型Function Types
定义索引签名
因为obj.property会被当作obj[\"property\"]执行
注意字符串索引签名会强制要求所有属性返回值与字符串索引返回值相同
这段翻译有问题,推荐看英文版本理解
字符串
数字
这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。也就是说用 100(一个number)去索引等同于使用\"100\"(一个string)去索引,因此两者需要保持一致。
可以同时使用,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
支持两种索引签名
将索引设为只读
索引类型Indexable Types
属性示例
方法示例
可用于描述公共属性和方法
接口仅描述实例部分
如果需要描述构造器(静态部分)可以考虑不直接继承,而是用检查的方式
类静态部分与实例部分的区别
类类型Class Types
单继承
简单情况示例
定义完全相同,可以多继承
上例中,如果color的类型不同会报错
定义不同,不可多继承
如果不同父接口中有相同的属性声明
多继承
继承接口Extending Interfaces
一个对象可以同时做为函数和对象使用,并带有额外的属性。
混合类型 Hybrid Types
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。
这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时这个接口类型只能被这个类或其子类所实现
接口同样会继承到类的private和protected成员。
接口继承类Interfaces Extending Classes
接口Interfaces
constructor
构造器
this
派生类的构造函数必须调用 super()
在构造函数里访问 this的属性之前,一定要调用 super()
不需要override修饰符,可以调用super
重写
很意外?需要深入了解TS的混入机制
交叉类型是一种解决方式
不允许多继承
继承
属性方法都默认为public
public
private不可在外部调用
private不可重写
private
protected 不可在外部调用
注意protected是可继承的,子类中的重写可以是public
protected
兼容性问题
公共,私有与受保护的修饰符
允许在类的构造函数中赋值
readonly 声明
不允许在类构造中赋值,仅能在定义处赋值
static readonly
把声明和赋值合并至一处
有啥好处???
参数属性
简略写法
get / set
存取器要求你将编译器设置为输出ECMAScript 5或更高。
只带有 get不带有 set的存取器自动被推断为 readonly。
存取器
static
即便是在类内部要访问这个属性的时候,都要写作 类名.属性名
静态属性
abstract
抽象类
构造函数
接口一章的“接口继承类”
把类当做接口使用
高级技巧
类class
普通函数
匿名函数
捕获外部变量
函数
参数类型
在完整函数类型写法中,在函数和返回值类型之间使用( =>)符号
返回值类型
函数类型包含两部分
为函数定义类型
参数名只是为了可读性,可以不统一
无返回值的情况下void不可省略
类型定义
接口
用在哪里的
书写完整函数类型
编译器会按上下文归类,推断类型
推断类型
编译器检查用户是否为每个参数都传入了值
传入更多值也是不允许的
可选参数应放在必须参数后面
可选参数
默认参数是可选参数
带默认值的参数可以出现在必须参数前面,此时只有在明确的传入 undefined值时才会获得默认值。
默认参数
可不传值的情况
可选参数和默认参数
可以用在完整函数类型定义上
剩余参数
函数类型
理解this原理
JavaScript中,this的值只在函数被调用时才会指定
运行会报错
顶级的非方法式调用会将 this视为window。 (注意:在严格模式下, this为undefined而不是window)。
如果编译器设置了--noImplicitThis那么在使用function()的地方会有错误警告
this与function函数
箭头函数能保存函数创建时的 this值而不是调用时的值
在VS中,用鼠标放在this上还可以看到类型提示
this和箭头函数
注:此处可能是文档未更新导致的问题实测在VS中不写this参数,严格模式也不会报错,可以正常运行
--noImplicitThis不会报错
this参数 应在参数表的第一位
显式的this参数可以令this在调用时的类型不为any
当回调被调用的时候,会被当成一个普通函数调用在回调方法中的this将为undefined。
利用this避免错误
没看懂
this参数在回调函数中
this 参数
首先要声明重载函数,仅声明!
声明时要注意顺序,在重载时是按照顺序来查找对应的!
然后要写出重载的具体实现(没错,需要自己实现!)
注意TS重载的实现是与静态语言不同的!原文中并没有强调如下格式
示例1 单参数
示例2 多参数
示例3 可选参数
重载
函数Functions
概念与C#基本相同
泛型定义
泛型变量
泛型类型
泛型类
extends
注意此处中文翻译有误,请参看英文版
在泛型约束中使用类型参数
在TypeScript使用泛型创建工厂函数时需要引用构造函数的类类型。
使用原型属性推断并约束构造函数与类实例的关系
在泛型里使用类类型
泛型约束
泛型Generics
默认从0开始
C++
C#
ObjectC
两个相同值的成员,第二个成员的名称被视作第一个成员的别名
python
允许枚举值重复的语言
通过自定义构造函数可以达到重复的效果
Java
不允许枚举值重复的语言
容易混淆的地方
允许值重复
常量表格式
原文说法:不被初始化的枚举要么放在第一位,要么放在其他被常量初始化过的枚举之后
举例
换个说法:必须对对非常量表格式之后的每一个枚举赋值,不可省略
非常量表达式
允许用表达式赋值
重复的值会被替代
反向映射
会自动合并为一个枚举
不可重复
只有一个声明可以省略第一个枚举元素的初始化表达式
很容易重复
多个声明
数字枚举
必须用字符串字面量,或另外一个字符串枚举成员进行初始化
不支持反向映射
允许重复
允许多个声明
字符串枚举
混合字符串和数字成员
非特殊情况不推荐使用
异构枚举Heterogeneous enums
它是枚举的第一个成员且没有初始化器,这种情况下它被赋予值 0:
它不带有初始化器且它之前的枚举成员是一个 数字常量。
常数枚举表达式指可以在编译阶段求值的表达式。
枚举成员使用 常量枚举表达式初始化。
当满足如下条件之一时,枚举成员被当作是常量:
否则为计算量
计算的和常量成员
不带有初始值的常量枚举成员
值被初始化为任何字符串的字面量
值被初始化为任何数字字面量
值被初始化为应用了一元运算符的数字字面量(例如负号)
字面量枚举成员 literal enum members
可用于定义变量类型
枚举成员成为了类型
枚举类型本身变成了每个枚举成员的 联合
当所有枚举成员都拥有字面量枚举值时
联合枚举与枚举成员的类型Union enums and enum member types
枚举是在运行时真正存在的对象,可当作实例化的对象使用
运行时的枚举
const enum
常量枚举只能使用常量枚举表达式
不同于常规的枚举,它们在编译阶段会被删除。常量枚举成员在使用的地方会被内联进来。
const枚举
declare enum
在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的
外部枚举并不直接生成代码,直接引用外部枚举值会报undefined,外部枚举用于第三方库等情况
外部枚举
会生成代码
生成内联代码
const enum
不生成相关代码
declare const enum
几种枚举的区别
直接遍历枚举会获得数字和表达式
遍历需要过滤
可以参与位运算
说明
枚举的遍历
数字/字符串 和 枚举是通用的
枚举与其他类型的转化
枚举Enums
在省略类型时,编译器会推断类型
当需要在几个表达式中推断类型时,会使用这些表达式的类型来推断最佳通用类型
如果无法推断,则使用联合类型
最佳通用类型Best common type
上下文类型Contextual Type
类型推论Type Inference
TypeScript里的类型兼容性是基于结构子类型的(structural subtyping)。
...
结构类型Structural typing
JS / TS
Lua
数据类型的兼容性或等价性是通过明确的声明和/或类型的名称来决定
名义类型nominal typing
介绍
关于可靠性的注意事项
如果x要兼容y,那么y至少具有与x相同的属性
检查函数参数时使用相同的规则
比较原始类型和对象类型
允许忽略参数
要查看x是否能赋值给y,首先看它们的参数列表。 x的每个参数必须能在y里找到对应类型的参数。
参数
源函数的返回值类型必须是目标函数返回值类型的子类型
返回值
只有当源函数参数能够赋值给目标函数或者反过来时才能赋值成功
???
函数参数双向协变Function Parameter Bivariance
可选参数及剩余参数Optional Parameters and Rest Parameters
函数重载
有点反认知,仔细看例子
比较两个函数
枚举类型与数字类型兼容,并且数字类型与枚举类型兼容。
不同枚举类型之间是不兼容的。
枚举
比较两个类类型的对象时,只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内。
在类章节有相关内容
类的私有成员和受保护成员
类
示例1 不作为成员类型
示例2 作为成员类型
泛型参数仅在被当作成员类型时才被比较
对于没指定泛型类型的泛型参数时,会把所有泛型参数当成any比较。
泛型
子类型
赋值
高级主题
类型兼容性Type Compatibility
定义:交叉类型是将多个类型合并为一个类型, 它包含了所需的所有类型的特性。
这个示例是错误的
可以通过编译的原因是交叉类型的定义正确
错误原因是没有对result的log方法赋值使用for...in...仅遍历的属性而没有遍历方法
正常用法
个人感觉就是多继承
不要对基础类型做交叉
错误用法
正确用法
这个特点与展开(Spread)不同,展开会覆盖
注意到同名属性做了交叉而不是覆盖因此可以得到交换律
属性名相同但类型不同
X&Y 和 Y&X 是兼容的
交换律
交叉类型 &Intersection Types
定义:联合类型表示一个值可以是几种类型之一
只能访问联合类型的所有类型里共有的成员。
联合类型 |Union Types
断言
上例中,pet is Fish就是类型谓词。 谓词为 parameterName is Type这种形式, parameterName必须是来自于当前函数签名里的一个参数名。
TypeScript不仅知道在 if分支里 pet是 Fish类型; 它还清楚在 else分支里,一定 不是 Fish类型,一定是 Bird类型。
用户自定义类型保护
typeof v === \"typename\"
typeof v !== \"typename\"
限制1:语法限定
\"number\"
\"string\"
\"boolean\"
\"symbol\"
除以上四个类型外的字符串不被视为类型保护
限制2:typename限定
typeof 类型保护
限定:instanceof右侧必须是一个构造函数
之后的部分没看懂
instanceof类型保护
类型保护与区分类型Type Guards and Differentiating Types
默认null和undefined是所有类型的子类
strictNullChecks 可以避免null和undefined自动成为子类
可选参数示例
可选属性示例
使用了 --strictNullChecks,可选参数/属性会被自动地加上 | undefined:
可选参数和可选属性
类型保护
类型断言 !
目标:在联合类型中去除null
类型保护和类型断言
可以为null的类型Nullable types
与接口不同
别名不会新建一个类型
类型别名也可以是泛型
类型别名可以在属性里引用自己
注意与上一条“可以在属性里引用自己”的区别
类型别名不能出现在声明右侧的任何地方。
接口创建了一个新的名字, 类型别名并不创建新名字
类型别名不能被 extends和 implements(自己也不能 extends和 implements其它类型)
接口 vs. 类型别名
类型别名Type Aliases
可以实现类似枚举类型的字符串
区分函数重载
字符串字面量类型String Literal Types
数字字面量类型Numeric Literal Types
枚举成员类型Enum Member Types
具有普通的单例类型属性— 可辨识的特征。
一个类型别名包含了那些类型的联合— 联合。
此属性上的类型保护。
合并单例类型,联合类型,类型保护和类型别名来创建一个叫做 可辨识联合的高级模式,它也称做 标签联合或 代数数据类型。
方法1 启动strictNullChecks并且指定一个返回值类型
方法2 使用never
完整性检查
可辨识联合Discriminated Unions
定义:多态的 this类型表示的是某个包含类或接口的 子类型。 这被称做 F-bounded多态性。
多态的 this类型Polymorphic this types
使用索引类型,编译器就能够检查使用了动态属性名的代码
对于任何类型 T, keyof T的结果为 T上已知的公共属性名的联合。
索引类型查询 操作符 keyof index type query operator.
索引类型访问 操作符 T[K]indexed access operator
索引类型和字符串索引签名
索引类型Index types
映射类型Mapped types
高级类型Advanced Types
自ECMAScript 2015起,symbol成为了一种新的原生类型,就像number和string一样。
symbol类型的值是通过Symbol构造函数创建的。
Symbols是不可改变且唯一的。
像字符串一样,symbols也可以被用做对象属性的键。
Symbols也可以与计算出的属性名声明相结合来声明对象的属性和类成员。
内置symbols用来表示语言内部的行为???
内置symbols
Symbols
当一个对象实现了Symbol.iterator属性时,我们认为它是可迭代的
可迭代性
迭代的是对象的 键 的列表
for ... of
迭代对象的键对应的值
for ... in
区别示例
迭代对象不同
可以操作任何对象
关注于迭代对象的值
for ... of
操作对象不同
for of/in 的区别
迭代器和生成器Iterators and Generators
其定义和其他语言是一样的,区别就是需要public的成员修饰符为 export
单文件示例
使用引用标签表示关联
方法1,把所有的输入文件编译为一个输出文件
方法2,页面上通过 <script>标签顺序引入JavaScript文件
确保所有编译后的代码都被加载
分离到多文件
形如 import q = x.y.z
别名Aliases
外部命名空间
使用其他的JS库
命名空间namespace
建议在看模块之前先看命名空间,原文应该是写反了顺序
定义:个人理解就是文件级的namespace
导出声明 export
用于重命名
导出语句
用于扩展其它模块
导出多模块
重新导出
导出
导入示例
导入重命名示例
导入一个模块中的某个导出内容
将整个模块导入到一个变量,并通过它来访问模块的导出部分
具有副作用的导入模块
导入
限定:每个模块最多只能有一个default导出
默认导出类示例
默认导出函数示例
类和函数声明可以直接被标记为默认导出标记为默认导出的类和函数的名字是可以省略的。
default导出也可以是一个值
export =语法定义一个模块的导出对象
若使用export =导出一个模块,则必须使用TypeScript的特定语法import module = require(\"module\")来导入此模块。
export = 和 import = require()
默认导出
生成模块代码
可选的模块加载和其它高级加载场景
外部模块
外部模块简写
模块声明通配符
使用其它的JavaScript库
尽可能地在顶层导出
如果仅导出单个 class 或 function,使用 export default
如果要导出多个对象,把它们放在顶层里导出
明确地列出导入的名字
使用命名空间导入模式当你要导出大量内容的时候
创建模块结构指导
使用重新导出进行扩展
模块modules
使用命名空间
使用模块
别对模块使用 ///<reference> 这是namespace用的
不必要的命名空间
命名空间和模块的陷阱
模块的取舍
命名空间和模块Namespaces and Modules
定义:模块解析是指编译器在查找导入模块内容时所遵循的流程
如果定位失败,且模块名是非相对的,编辑器会尝试定位一个外部模块声明
如果外部声明也找不到,那么报错
定位策略: classic 或 Node
基础知识
以 / ./ ../ 开头
自己写的模块应该是使用相对导入
相对导入
非以上格式的皆为非相对导入
可以相对于baseUrl或者通过路径映射来解析
或者被解析为外部模块
非相对导入
相对 vs. 非相对模块导入
相对导入的模块是相对于导入它的文件进行解析的。
非相对导入的模块从包含导入文件的目录开始依次向上级目录遍历
Classic
相对路径
非相对路径
NodeJS如何解析模块
模仿NodeJS
增加TypeScript源文件的扩展名( .ts,.tsx和.d.ts)
TypeScript在 package.json里使用字段\"types\"来表示类似\"main\"的意义
相对路径示例
非相对路径示例
TypeScript如何解析模块
工程源码结构与输出结构不同可能会打乱源文件路径关系TS用一些额外的标记记录此过程中都发生了哪些转换。
在运行时模块都被放到了一个文件夹里
设置baseUrl来告诉编译器到哪里去查找模块。
所有非相对模块导入都会被当做相对于 baseUrl。
命令行中baseUrl的值(如果给定的路径是相对的,那么将相对于当前路径进行计算)
‘tsconfig.json’里的baseUrl属性(如果给定的路径是相对的,那么将相对于‘tsconfig.json’路径进行计算)
baseUrl的值由以下两者之一决定:
Base URL
有时模块不是直接放在baseUrl下面
TS通过使用tsconfig.json文件里的\"paths\"来支持这样的声明映射。
通过\"paths\"我们还可以指定复杂的映射,包括指定多个回退位置。
利用rootDirs指定虚拟目录
路径映射
跟踪模块解析
使用--noResolve
附加的模块解析标记
常见问题
Node
可以通过moduleResolution来标记指定策略
模块解析策略
模块解析Module Resolution
编译器将针对同一个名字的两个独立声明合并为单一声明。
合并后的声明同时拥有原先两个声明的特性。
任何数量的声明都可被合并;不局限于两个声明。
定义
接口的非函数的成员应该是唯一的。如果它们不是唯一的,那么它们必须是相同的类型。如果两个接口中同时声明了同名的非函数成员且它们的类型不同,则编译器会报错。
当接口 A与后来的接口 A合并时,后面的接口具有更高的优先级。
签名里有一个参数的类型是单一的字符串字面量
优先级特例
优先级的意义是什么?实现接口时并不在意顺序啊??
合并接口
导出成员的合并
导出成员仅在其原有的(合并前的)命名空间内可见
合并之后,从其它命名空间合并进来的成员无法访问非导出成员
非导出成员
合并命名空间
用于创建内部类
TS不直接支持内部类
用于扩展
命名空间与类合并
用于扩展?
命名空间与方法合并
扩展枚举方法
命名空间与枚举合并
命名空间与其他合并
可参考混入功能
类不能与其它类或变量合并
非法的合并
模块扩展
全局扩展
声明合并Declaration Merging
一种嵌入式的类似XML的语法
文件扩展名 .tsx
具体内容略过
JSX
略过
装饰器Decorators
这和接口继承类的用法有什么区别?
混入Mixins
是包含单个XML标签的单行注释。 注释的内容会做为编译器指令使用。
三斜线指令仅可放在包含它的文件的最顶端。 一个三斜线指令的前面只能出现单行或多行注释,这包括其它的三斜线指令。 如果它们出现在一个语句或声明之后,那么它们会被当做普通的单行注释,并且不具有特殊的涵义。
声明文件依赖
/// <reference path=\"...\" />
从这里开始就看不懂了
预处理输入文件
错误
如果指定了--noResolve编译选项,三斜线引用会被忽略
声明包(package)依赖
仅当在你需要写一个d.ts文件时才使用这个指令。
/// <reference types=\"...\" />
这个指令告诉编译器在编译过程中不要包含这个默认库
当传递了--skipDefaultLibCheck时,编译器只会忽略检查带有/// <reference no-default-lib=\"true\"/>的文件。
/// <reference no-default-lib=\"true\"/>
/// <amd-module />
已废弃,用module代替
/// <amd-dependency />
三斜线指令Triple-Slash Directives
JS文件类型检查Type Checking JavaScript Files
手册Handbook
结构
不要使用Number,String,Boolean,Object(大写),改用小写的number,string,boolean,object
基础类型
原因说明
注意,直接运行例子是可以运行的,正常返回undefined。但是如果试图获取x的name属性,那么就会报错。原因见上。
不要定义一个从来没使用过其类型参数的泛型类型。
普通类型
无回调的函数写void
回调函数返回值类型
不要在回调函数里使用可选参数
回调函数里的可选参数
不要因为回调函数参数个数不同而写不同的重载:
应该只使用最大参数个数写一个重载:
为什么:回调函数总是可以忽略某个参数的,因此没必要为参数少的情况写重载。 参数少的回调函数首先允许错误类型的函数被传入,因为它们匹配第一个重载。
重载与回调函数
回调函数类型
不要把一般的重载放在精确的重载前面
顺序
不要为仅在末尾参数不同时写不同的重载:
应该尽可能使用可选参数:
使用可选参数
使用联合类型
规范Do's and Don'ts
类型
值
命名空间
核心概念
内置组合
用户组合
简单的组合:一个名字,多种意义
利用interface添加
使用namespace添加
使用export =或import
高级组合
声明文件原理:深入探究
深入DeepDive
模板Templates
发布Publishing
使用Consumption
声明文件Declaration Files
项目配置Project Configuration
函数表达式与箭头函数表达式的区别是什么
为什么类内声明变量时不需要let?
== 比较值,如果类型不同,则先转化为同类型
=== 严格比较,类型不同会返回false
== === 的区别是啥
简单讲,就是可以在 ts 中调用的 js 的声明文件,类似c++中的“*.h” 头文件,不过和 “*.h”不一样的是,它完全是个声明文件,没有任何实现代码。
在 “.d.ts” 的每一个段落中,除了最外层为 interface 外,其他的都需要 declare 关键词,而且这个词只在最外层出现。
.d.ts是什么文件
请查看jsx章节
.tsx是什么文件
Promise的用法?
现在ES5已经可以使用Map
使用set方法和[]都可以赋值,但是只有set才检查类型
用for...each
用 iterator
直接使用for...in...遍历不会进入循环
但是Map有坑:
Dictionary的用法?
undefined其实是个变量
void 0 则绝对返回undefined
详细解释,注意其他写法
“void 0” 与 “undefined”的区别是什么
问题
TypeScript
0 条评论
下一页