详解Vue3.0 前的 TypeScript 最佳入门实践(3)

interface User { name: string age: number } type User = { name: string age: number }; interface SetUser { (name: string, age: number): void; } type SetUser = (name: string, age: number): void;

都允许拓展(extends):

interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type , type 也可以 extends interface 。 虽然效果差不多,但是两者语法不同

interface extends interface

interface Name { name: string; } interface User extends Name { age: number; }

type extends type

type Name = { name: string; } type User = Name & { age: number };

interface extends type

type Name = { name: string; } interface User extends Name { age: number; }

type extends interface

interface Name { name: string; } type User = Name & { age: number; }

2. 不同点

type 可以而 interface 不行

type 可以声明基本类型别名,联合类型,元组等类型

// 基本类型别名 type Name = string // 联合类型 interface Dog { wong(); } interface Cat { miao(); } type Pet = Dog | Cat // 具体定义数组每个位置的类型 type PetList = [Dog, Pet]

type 语句中还可以使用 typeof 获取实例的 类型进行赋值

// 当你想获取一个变量的类型时,使用 typeof let div = document.createElement('div'); type B = typeof div

其他骚操作

type StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary<string, Person>; type Callback<T> = (data: T) => void; type Pair<T> = [T, T]; type Coordinates = Pair<number>; type Tree<T> = T | { left: Tree<T>, right: Tree<T> };

interface 可以而 type 不行

interface 能够声明合并

interface User { name: string age: number } interface User { sex: string } /* User 接口为 { name: string age: number sex: string } */

interface 有可选属性和只读属性

可选属性

接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。 例如给函数传入的参数对象中只有部分属性赋值了。带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个 ? 符号。如下所示

interface Person { name: string; age?: number; gender?: number; }

只读属性

顾名思义就是这个属性是不可写的,对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly 来指定只读属性,如下所示:

interface User { readonly loginName: string; password: string; }

上面的例子说明,当完成User对象的初始化后loginName就不可以修改了。

3.4 实现与继承: implements vs extends

extends 很明显就是ES6里面的类继承,那么 implement 又是做什么的呢?它和 extends 有什么不同?

implement ,实现。与C#或Java里接口的基本作用一样, TypeScript 也能够用它来明确的强制一个类去符合某种契约

implement基本用法:

interface IDeveloper { name: string; age?: number; } // OK class dev implements IDeveloper { name = 'Alex'; age = 20; } // OK class dev2 implements IDeveloper { name = 'Alex'; } // Error class dev3 implements IDeveloper { name = 'Alex'; age = '9'; }

而 extends 是继承父类,两者其实可以混着用:

class A extends B implements C,D,E

搭配 interface 和 type 的用法有:

详解Vue3.0 前的 TypeScript 最佳入门实践

3.5 声明文件与命名空间: declare 和 namespace

前面我们讲到Vue项目中的 shims-tsx.d.ts 和 shims-vue.d.ts ,其初始内容是这样的:

// shims-tsx.d.ts import Vue, { VNode } from 'vue'; declare global { namespace JSX { // tslint:disable no-empty-interface interface Element extends VNode {} // tslint:disable no-empty-interface interface ElementClass extends Vue {} interface IntrinsicElements { [elem: string]: any; } } } // shims-vue.d.ts declare module '*.vue' { import Vue from 'vue'; export default Vue; }

declare :当使用第三方库时,我们需要引用它的声明文件,才能获得对应的代码补全、接口提示等功能。

这里列举出几个常用的:

declare var 声明全局变量

declare function 声明全局方法

declare class 声明全局类

declare enum 声明全局枚举类型

declare global 扩展全局变量

declare module 扩展模块

namespace :“内部模块”现在称做“命名空间”

module X { 相当于现在推荐的写法 namespace X { )

跟其他 JS 库协同

类似模块,同样也可以通过为其他 JS 库使用了命名空间的库创建 .d.ts 文件的声明文件,如为 D3 JS 库,可以创建这样的声明文件:

declare namespace D3{ export interface Selectors { ... } } declare var d3: D3.Base;

所以上述两个文件:

shims-tsx.d.ts , 在全局变量 global 中批量命名了数个内部模块。 shims-vue.d.ts ,意思是告诉 TypeScript *.vue 后缀的文件可以交给 vue 模块来处理。

3.6 访问修饰符: private 、 public 、 protected

其实很好理解:

默认为 public

当成员被标记为 private 时,它就不能在声明它的类的外部访问,比如:

class Animal { private name: string; constructor(theName: string) { this.name = theName; } } let a = new Animal('Cat').name; //错误,‘name'是私有的

protected 和 private 类似,但是, protected 成员在派生类中可以访问

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/aba0cc8c4c0d4e712aa3e1882ebc695a.html