TypeScript与JavaScript不同之处系列(二) ===> 接口
本系列目的: 列出TypeScript与JavaScript的不同点, 缩小文档内容, 提高学习速度. 原文档地址: https://www.tslang.cn/index.html
全系列目录
- 1.基础类型 https://blog.csdn.net/c_kite/article/details/85232021
- 2.接口 https://blog.csdn.net/c_kite/article/details/85262016
- 3.类 https://www.geek-share.com/detail/2797042169.html
- 4.函数 https://www.geek-share.com/detail/2797042166.html
- 5.泛型 https://www.geek-share.com/detail/2797042161.html
- 6.枚举 https://www.geek-share.com/detail/2797042158.html
- 7.类型推论, 类型兼容性 https://www.geek-share.com/detail/2797042155.html
- 8.高级类型 https://www.geek-share.com/detail/2797042153.html
- 9.命名空间, 三斜线指令 https://www.geek-share.com/detail/2797042143.html
文章目录
1. 对象
1.1. 最简单的使用例子
interface LabelledValue { label: string; } function printLabel(labelledObj: LabelledValue) { console.log(labelledObj.label); } let myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj);
1.2. 可选属性
带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号
需要注意的是, 即使是可选属性也要遵循基本原则, 如下面这个例子, 如果传入的参数属性不在SquareConfig中的话也会报错
interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): {color: string; area: number} { let newSquare = {color: "white", area: 100}; if (config.color) { newSquare.color = config.color; } if (config.width) { newSquare.area = config.width * config.width; } return newSquare; } let mySquare = createSquare({color: "black"}); let myError = createSquare({color: "black", gkd: '1'}); // 报错
1.2.1. 额外检查
上面例子可以看到如果, 传入
gkd属性就会报错, 那么如何绕开这些错误呢.
// 1. 使用类型断言(类型断言参见下面的介绍) let mySquare = createSquare({ width: 100, gkd: '1'} as SquareConfig); // 2. 增加检验属性 interface SquareConfig { color?: string; width?: number; [propName: string]: any; }
官方建议, 在这里,如果支持传入gkd属性到createSquare,你应该修改SquareConfig定义来体现出这一点。
1.2.1.1. 类型断言
通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。
TypeScript会假设你,程序员,已经进行了必须的检查。
类型断言有两种形式。 其一是“尖括号”语法:
let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length; // 另一个为as语法: let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
两种形式是等价的。 至于使用哪个大多数情况下是凭个人喜好;然而,当你在
TypeScript里使用JSX时,只有 as语法断言是被允许的
1.3. 只读属性
一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用
readonly来指定只读属性:
interface Point { readonly x: number; readonly y: number; } let p1: Point = { x: 10, y: 20 }; p1.x = 5; // error!, 因为Point只读
TypeScript具有
ReadonlyArray<T>类型,它与
Array<T>相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:
let a: number[] = [1, 2, 3, 4]; let ro: ReadonlyArray<number> = a; ro[0] = 12; // error! ro.push(5); // error! ro.length = 100; // error! a = ro; // error! // 可以用类型断言重写: a = ro as number[];
2. 可索引类型
它描述了对象索引的类型,还有相应的索引返回值类型, 例:
interface StringArray { [index: string]: number; length: number; // 可以,length是number类型 name: string; // 错误,`name`的类型与索引类型返回值的类型不匹配 } let myArray: StringArray; myArray['gkd'] = 123; let myStr: number = myArray['gkd'];
3. 函数
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型
interface SearchFunc { (source: string, subString: string): boolean; } //对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 let mySearch: SearchFunc; mySearch = function(src: string, sub: string): boolean { let result = src.search(sub); return result > -1; } // 如果你不想指定类型也可以这么写 let mySearch: SearchFunc; mySearch = function(src, sub) { let result = src.search(sub); return result > -1; }
4. 类类型
类类型按照js话来讲, 就是对象.
4.1. 简单使用
// 例1 interface ClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; } constructor(h: number, m: number) { } }
4.2. 继承
interface Shape { color: string; } interface PenStroke { penWidth: number; } interface Square extends Shape, PenStroke { sideLength: number; } let square = <Square>{}; // 可以理解为Square类型的对象 square.color = "blue"; square.sideLength = 10; square.penWidth = 5.0; square.gkd= 5.0; // 报错 Property 'gkd' does not exist on type 'Square'.
4.3. 混合类型
为JavaScript其动态灵活的特点,有时你会希望一个对象可以同时具有上面提到的多种类型。一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性.
interface Counter { (start: number): string; interval: number; reset(): void; } function getCounter(): Counter { let counter = <Counter>function (start: number) { }; counter.interval = 123; counter.reset = function () { }; return counter; } let c = getCounter(); c(10); c.reset(); c.interval = 5.0;
4.4. 接口继承类
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员
class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control implements SelectableControl { select() { } }
- 点赞
- 收藏
- 分享
- 文章举报
- TypeScript与JavaScript不同之处系列(五) ===> 泛型
- TypeScript与JavaScript不同之处系列(四) ===> 函数
- TypeScript与JavaScript不同之处系列(三) ===> 类
- TypeScript与JavaScript不同之处系列(九) ===> 命名空间, 三斜线指令
- TypeScript与JavaScript不同之处系列(八) ===> 高级类型
- TypeScript与JavaScript不同之处系列(七) ===>类型推论, 类型兼容性
- TypeScript与JavaScript不同之处系列(六) ===>枚举
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- (三)我的JavaScript系列:不同调用方式的this指向
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- 面向对象的javascript系列文章(1)接口——是一个标准委员会
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- Angular 4入门教程系列:12:TypeScript:类与接口
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
- 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解
- 从 JavaScript 到 TypeScript 系列