TypeScript 学习笔记5:Custom Types
2017-07-02 20:21
369 查看
原文链接:https://leanpub.com/essentialtypescript/read#leanpub-auto-custom-types
1. 使用interface定义新的类型
1.1. 定义interface
1.2. 使用interface
1.3. 遵守interface 协议
这两个变量定义不合法,编译器会报错。因为,它们没有遵守 interface Todo 规定的协议,属性不完整。
1.4. 强制类型转换
这种写法告诉编译器 t1 符合 Todo 接口。虽然它不符合,但编译器不会报错。
1.5. optional 属性
completed 后面有个问号,指明:
1. completed 属性可有可无;
2. 如果有这个属性,必须是boolean类型。
所以,t2 没有completed属性,但它是符合 Todo 接口的。
1.6. 在接口中定义function
注意,函数名前面不用写 function 。
2. 使用interface描述function
2.1. 定义函数 interface
function 本身就是Object,函数体是它的一个属性,当然,它也可以有其他的属性。
1. 这个interface定义一个function接口,它模拟了 jQuery(selector) 这个函数。
2. 注意第二行,定义了一个没有名字的函数,括号中是参数声明,后面是返回值类型。没想通为什么要这么写,先背下来,反正就得这么写。
3. 第三行定义了一个属性 —— version。
2.2. 使用函数interface
说明:
1. 上图中,第七行定义了一个函数,函数名是 $,它遵从 jQuery 接口。
2. 第11行使用刚刚定义的 $ 函数,获取 id="container" 的DOM element。
3. 第12行,此时,TypeScript 可以推断出element的类型。
3. 给已有的interface添加属性
下面的代码模拟了 jQuery 的 data() 方法:
如果我们加上如下代码,会给 jQueryElement 添加 todo() 方法:
可以这么写:
4. enum
5. 匿名类型
回顾一下前面写的 totalLength 函数:
{ length: number } 定义了一个匿名的 interface。
6. Indexer
第2行代码,它给 [ ] 定义了明确的signature,有了这个定义,最后一行才会出现上下文提示,TypeScript 才知道 comments 变量是个 string[ ] 。
1. 使用interface定义新的类型
1.1. 定义interface
interface Todo { name: string; completed: boolean; }
1.2. 使用interface
var todo: Todo = { name: "Pick up drycleaning", completed: false };
1.3. 遵守interface 协议
var t1: Todo = {}; var t2: Todo = { name: "Pick up drycleaning" };
这两个变量定义不合法,编译器会报错。因为,它们没有遵守 interface Todo 规定的协议,属性不完整。
1.4. 强制类型转换
var t1 = <Todo>{};
这种写法告诉编译器 t1 符合 Todo 接口。虽然它不符合,但编译器不会报错。
1.5. optional 属性
interface Todo { name: string; completed?: boolean; } var t2: Todo = { name: "Pick up drycleaning" };
completed 后面有个问号,指明:
1. completed 属性可有可无;
2. 如果有这个属性,必须是boolean类型。
所以,t2 没有completed属性,但它是符合 Todo 接口的。
1.6. 在接口中定义function
interface ITodoService { add(todo: Todo): Todo; delete(todoId: number): void; getAll(): Todo[]; getById(todoId: number): Todo; }
注意,函数名前面不用写 function 。
2. 使用interface描述function
2.1. 定义函数 interface
function 本身就是Object,函数体是它的一个属性,当然,它也可以有其他的属性。
interface jQuery { (selector: string): HTMLElement; version: number; }说明:
1. 这个interface定义一个function接口,它模拟了 jQuery(selector) 这个函数。
2. 注意第二行,定义了一个没有名字的函数,括号中是参数声明,后面是返回值类型。没想通为什么要这么写,先背下来,反正就得这么写。
3. 第三行定义了一个属性 —— version。
2.2. 使用函数interface
说明:
1. 上图中,第七行定义了一个函数,函数名是 $,它遵从 jQuery 接口。
2. 第11行使用刚刚定义的 $ 函数,获取 id="container" 的DOM element。
3. 第12行,此时,TypeScript 可以推断出element的类型。
3. 给已有的interface添加属性
下面的代码模拟了 jQuery 的 data() 方法:
interface jQueryElement { data(name: string): any; data(name: string, data: any): jQueryElement; } interface jQuery { (selector: (string | any)): jQueryElement; fn: any; version: number; } var $ = <jQuery>function(selector) { // Find DOM element }; var todo = { name: "Pick up drycleaning" }; var element = $('#my-element'); element.data('todo', todo); var savedTodo = element.data('todo');第8行,fn:any ,这是jQuery提供的一种plugin模式。
如果我们加上如下代码,会给 jQueryElement 添加 todo() 方法:
$.fn.todo = function(todo?: Todo) { if(todo) { $(this).data('todo', todo); } else { return $(this).data('todo'); } }但是,只添加这些代码是不够的,因为,没有人知道 jQueryElement 添加了 data() 方法。我们需要把它添加到 interface jQueryElement 中:
interface jQueryElement { data(name: string): any; data(name: string, data: any): jQueryElement; todo(): Todo; todo(todo: Todo): jQueryElement; }但是,我们不希望这么做,如果这么做,就不叫plugin了,因为,每添加一个方法,都要修改jQueryElement的源代码。
可以这么写:
interface jQueryElement { data(name: string): any; data(name: string, data: any): jQueryElement; } interface jQueryElement { todo(): Todo; todo(todo: Todo): jQueryElement; }这不会造成 interface jQueryElement 的重复定义,第二个定义只是给第一个定义添加了两个method。我们可以添加无数个 interface jQuery 定义。
4. enum
interface Todo { name: string; state: number; /* New=1, Active=2, Complete=3, Deleted=4 */ }Todo 有四种状态,可以用number来表示。但我们希望它有更好的可读性,因为,遇到下面的代码,不容易猜测它的意图:
function deletTodo(todo: Todo) { if(todo.state != 3) { throw "Can't delete incomplete task!"; } }可以使用 enum 关键字,定义新的类型:
enum TodoState { New = 1, Active = 2, Complete = 3, Deleted = 4 } interface Todo { name: string; state: TodoState; } function deletTodo(todo: Todo) { if(todo.state != TodoState.Complete) { throw "Can't delete incomplete task!"; } }
5. 匿名类型
回顾一下前面写的 totalLength 函数:
function totalLength(x: (string | any[]), y: (string | any[])): number { var total: number = x.length + y.length; return total; }这个参数列表并不完美,其实,我们只是希望传入的参数带有 number 类型的 length 属性,可以这么写:
function totalLength(x: {length: number}, y: {length: number}): number { var total: number = x.length + y.length; return total; }
{ length: number } 定义了一个匿名的 interface。
6. Indexer
第2行代码,它给 [ ] 定义了明确的signature,有了这个定义,最后一行才会出现上下文提示,TypeScript 才知道 comments 变量是个 string[ ] 。
相关文章推荐
- Generics Types 泛型学习笔记
- 泛型(Generics Types)学习笔记
- OpenCv基础学习笔记之一[types_c.h][IplROI]
- ODAC(V9.5.15) 学习笔记(四)TCustomDADataSet(1)
- iOS学习笔记—— Storyboard里面的几种Segue区别:push,modal,popover,replace和custom
- iOS学习笔记—— Storyboard里面的几种Segue区别:push,modal,popover,replace和custom
- 泛型(Generics Types)学习笔记<一>
- OpenCv基础学习笔记之一[types_c.h][cvPoint]
- Data Types in the Kernel <LDD3 学习笔记>
- Partner Link Types, Partner Links, and Endpoint References(学习笔记)
- 泛型(Generics Types)学习笔记
- Generics Types 泛型学习笔记
- OpenCv基础学习笔记之一[types_c.h][IplImage]
- Generics Types 泛型学习笔记
- javascript高级程序设计学习笔记-Chapter 5: Reference Types
- ES权威指南[官方文档学习笔记]-59 Complex core field types
- Spring学习笔记-CustomEditorConfigurer
- [iOS学习]iOS开发中视图相关的小笔记:push、modal、popover、replace、custom
- Data Types in the Kernel <LDD3 学习笔记>
- ODAC(V9.5.15) 学习笔记(四)TCustomDADataSet(2)