TypeScript 学习笔记
[{“source”:{“position”:0,“lines”:[“
TypeScript 学习笔记
简介
在 TypeScript 的学习过程中,我发现这个语言有点抽象,团队成员那边已经给出了基础部分的学习笔记,我这边就记录一下学习过程中遇到的难点。
接口的妙用
混合类型
接口能够描述 JavaScript 里丰富的类型。 因为 JavaScript 其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。
一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性。
interface Counter {"]},"target":{"position":0,"lines":["TypeScript 学习笔记简介在 TypeScript 的学习过程中,我发现这个语言有点抽象,团队成员那边已经给出了基础部分的学习笔记,我这边就记录一下学习过程中遇到的难点。接口的妙用混合类型接口能够描述 JavaScript 里丰富的类型。 因为 JavaScript 其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性。interface Counter {"]},"type":"CHANGE"},{"source":{"position":28,"lines":["};类的一些特性存取器首先,我们从一个没有使用存取器的例子开始。class Employee {"]},"target":{"position":28,"lines":["};类的一些特性存取器首先,我们从一个没有使用存取器的例子开始。class Employee {"]},"type":"CHANGE"},{"source":{"position":59,"lines":["}我们可以修改一下密码,来验证一下存取器是否是工作的。当密码不对时,会提示我们没有权限去修改员工。只带有get不带有set的存取器自动被推断为readonly。 这在从代码生成.d.ts文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值。( TypeScript 简直是语法大杂烩, get 和 set 关键字都来了函数剩余参数必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用arguments来访问所有传入的参数。在TypeScript里,你可以把所有参数收集到一个变量里:function buildName(firstName: string, ...restOfName: string[]) {"]},"target":{"position":59,"lines":["}我们可以修改一下密码,来验证一下存取器是否是工作的。当密码不对时,会提示我们没有权限去修改员工。只带有get不带有set的存取器自动被推断为readonly。 这在从代码生成.d.ts文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值。( TypeScript 简直是语法大杂烩, get 和 set 关键字都来了函数剩余参数必要参数,默认参数和可选参数有个共同点:它们表示某一个参数。 有时,你想同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用arguments来访问所有传入的参数。在TypeScript里,你可以把所有参数收集到一个变量里:function buildName(firstName: string, ...restOfName: string[]) {"]},"type":"CHANGE"},{"source":{"position":63,"lines":["let employeeName = buildName(\"Joseph\", \"Samuel\", \"Lucas\", \"MacKinzie\");this这个好复杂,可以看文档枚举怪异的枚举值enum FileAccess {"]},"target":{"position":63,"lines":["let employeeName = buildName(\"Joseph\", \"Samuel\", \"Lucas\", \"MacKinzie\");this这个好复杂,可以看文档枚举怪异的枚举值enum FileAccess {"]},"type":"CHANGE"},{"source":{"position":71,"lines":["}断言尖括号语法: 尖括号语法是 TypeScript 中最早引入的断言形式。它使用 <Type> ,其中 Type 是您要将值断言为的目标类型。let someValue: any = \"Hello, World!\";"]},"target":{"position":71,"lines":["}断言尖括号语法: 尖括号语法是 TypeScript 中最早引入的断言形式。它使用 <Type> ,其中 Type 是您要将值断言为的目标类型。let someValue: any = \"Hello, World!\";"]},"type":"CHANGE"},{"source":{"position":73,"lines":["let strLength: number = (someValue as string).length;高级类型交叉类型(Intersection Types)交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如,Person & Serializable & Loggable 同时是 Person 和 Serializable 和 Loggable 。 就是说这个类型的对象同时拥有了这三种类型的成员。类型别名类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。type Name = string;"]},"target":{"position":73,"lines":["let strLength: number = (someValue as string).length;高级类型交叉类型(Intersection Types)交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如,Person & Serializable & Loggable 同时是 Person 和 Serializable 和 Loggable 。 就是说这个类型的对象同时拥有了这三种类型的成员。类型别名类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。type Name = string;"]},"type":"CHANGE"},{"source":{"position":93,"lines":["var s = people.next.next.next.name;#索引类型(Index types)(十分抽象的家伙使用索引类型,编译器就能够检查使用了动态属性名的代码。 例如,一个常见的JavaScript模式是从对象中选取属性的子集。function pluck(o, names) {"]},"target":{"position":93,"lines":["var s = people.next.next.next.name;#索引类型(Index types)(十分抽象的家伙使用索引类型,编译器就能够检查使用了动态属性名的代码。 例如,一个常见的JavaScript模式是从对象中选取属性的子集。function pluck(o, names) {"]},"type":"CHANGE"},{"source":{"position":111,"lines":["let unknown = getProperty(person, 'unknown'); // error, 'unknown' is not in 'name' | 'age'#映射类型一个常见的任务是将一个已知的类型每个属性都变为可选的:interface PersonPartial {"]},"target":{"position":111,"lines":["let unknown = getProperty(person, 'unknown'); // error, 'unknown' is not in 'name' | 'age'#映射类型一个常见的任务是将一个已知的类型每个属性都变为可选的:interface PersonPartial {"]},"type":"CHANGE"},{"source":{"position":123,"lines":["type ReadonlyPerson = Readonly<Person>;#由映射类型进行推断现在你了解了如何包装一个类型的属性,那么接下来就是如何拆包。 其实这也非常容易:function unproxify<T>(t: Proxify<T>): T {"]},"target":{"position":123,"lines":["type ReadonlyPerson = Readonly<Person>;#由映射类型进行推断现在你了解了如何包装一个类型的属性,那么接下来就是如何拆包。 其实这也非常容易:function unproxify<T>(t: Proxify<T>): T {"]},"type":"CHANGE"},{"source":{"position":131,"lines":["let originalProps = unproxify(proxyProps);注意这个拆包推断只适用于同态的映射类型。 如果映射类型不是同态的,那么需要给拆包函数一个明确的类型参数。命名空间和模块使用命名空间命名空间是位于全局命名空间下的一个普通的带有名字的 JavaScript 对象。 这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过 --outFile 结合在一起。 命名空间是帮你组织 Web 应用不错的方式,你可以把所有依赖都放在 HTML 页面的 <script> 标签里。但就像其它的全局命名空间污染一样,它很难去识别组件之间的依赖关系,尤其是在大型的应用中。使用模块像命名空间一样,模块可以包含代码和声明。 不同的是模块可以声明它的依赖。模块会把依赖添加到模块加载器上(例如 CommonJs / Require.js )。 对于小型的 JS 应用来说可能没必要,但是对于大型应用,这一点点的花费会带来长久的模块化和可维护性上的便利。 模块也提供了更好的代码重用,更强的封闭性以及更好的使用工具进行优化。对于 Node.js 应用来说,模块是默认并推荐的组织代码的方式。从 ECMAScript 2015 开始,模块成为了语言内置的部分,应该会被所有正常的解释引擎所支持。 因此,对于新项目来说推荐使用模块做为组织代码的方式。"]},"target":{"position":131,"lines":["let originalProps = unproxify(proxyProps);
注意这个拆包推断只适用于同态的映射类型。 如果映射类型不是同态的,那么需要给拆包函数一个明确的类型参数。
命名空间和模块
使用命名空间
命名空间是位于全局命名空间下的一个普通的带有名字的 JavaScript 对象。 这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过 —outFile 结合在一起。 命名空间是帮你组织 Web 应用不错的方式,你可以把所有依赖都放在 HTML 页面的
但就像其它的全局命名空间污染一样,它很难去识别组件之间的依赖关系,尤其是在大型的应用中。
使用模块
像命名空间一样,模块可以包含代码和声明。 不同的是模块可以_声明_它的依赖。
模块会把依赖添加到模块加载器上(例如 CommonJs / Require.js )。 对于小型的 JS 应用来说可能没必要,但是对于大型应用,这一点点的花费会带来长久的模块化和可维护性上的便利。 模块也提供了更好的代码重用,更强的封闭性以及更好的使用工具进行优化。
对于 Node.js 应用来说,模块是默认并推荐的组织代码的方式。
从 ECMAScript 2015 开始,模块成为了语言内置的部分,应该会被所有正常的解释引擎所支持。 因此,对于新项目来说推荐使用模块做为组织代码的方式。
”]},“type”:“CHANGE”}]