TypeScript发现与理解


1. 模块

模块的特性

  1. ES6的模块自动采用严格模式;
  2. 在ES6模块中,顶层的this的值是undefined,不应该在顶层代码使用this;
  3. export语句输出的接口与其对应的值是动态绑定关系,即通过该接口,可以获取到模块内部实时的值;这一点与CommonJS规范完全不同,CommonJS模块输出的是值的缓存,不存在动态更新;
  4. export 和 import 命令可以并且只能出现在模块顶层的任意位置;如果export 和 import 命令处于块级作用域内,就会报错;这是因为如果export 和 import 命令处于代码块之中,就没法做静态优化了,违背了ES6模块的设计初衷;
  5. 因为:export default命令的本质是:将该命令后面的值,赋给default变量,然后输出一个叫做default的量;
    所以:
    1. 可以直接将一个值写在export default之后;
    2. export default之后不能跟变量声明语句;
  6. import后面的from指定模块文件的位置,可以是相对路径或者绝对路径,.js后缀也可以省略;如果from后面指定的不是路径,只是一个模块名字,那么必须有配置文件能使JavaScript引擎找到该模块的位置;
  7. import命令具有提升效果,会提升到整个模块的顶部,首先执行。这种行为的本质是:import命令是编译阶段执行的,所以它会在所有代码运行之前执行;
  8. 由于import语句是在编译阶段执行,所以import语句中不能包含表达式、变量等只能在运行时才能得到结果的语法结构;
  9. 如果有相同的多条import语句,那么只会执行一次同一条import语句;
  10. 由于 ES6 输入的模块变量,只是一个“符号连接”,所以这个变量是只读的,对它进行重新赋值会报错;
  11. 在 Node 环境中,使用import命令加载 CommonJS 模块,Node 会自动将module.exports属性,当作模块的默认输出,即等同于export default;
  12. 采用require命令加载 ES6 模块时,ES6 模块的所有输出接口,会成为输入对象的属性。
  13. ES6模块与CommonJS模块的区别:
  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
  • ES6 模块之中,顶层的this指向undefined;CommonJS 模块的顶层this指向当前模块。

模块导入和导出的各种写法

导出

有以下几种导出方法:

  1. 导出声明:
    直接在(变量、函数、类型、类型别名、接口)声明前添加export关键字;
    示例如下:
    export const numberRegexp = /^[0-9]+$/;
    
    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
                return s.length === 5 && numberRegexp.test(s);
        }
    }
    
  2. 导出语句:
    导出语句可以把需要导出的实例一块导出,也可以对导出的部分重新命名;
    示例如下:
    export const numberRegexp = /^[0-9]+$/;
    
    class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
                return s.length === 5 && numberRegexp.test(s);
            }
    }
    
    export { ZipCodeValidator,numberRegexp };
    export { ZipCodeValidator as mainValidator };
    
  3. 重新导出:
    我们经常会去扩展其它模块,并且只导出那个模块的部分内容。 重新导出功能并不会在当前模块导入那个模块或定义一个新的局部变量;
    示例如下:
    // 导出原先的类但做了重命名
    export {ZipCodeValidator as RegExpBasedZipCodeValidator} from "./ZipCodeValidator";
    
  4. 默认导出:
    每个模块都可以有一个default导出。 默认导出使用default关键字标记;并且一个模块只能够有一个default导出。 需要使用一种特殊的导入形式来导入default导出。标记为默认导出的实体可以省略名字;
    示例如下:
    export default function (s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
    

导入

模块的导入操作与导出一样简单。 可以使用以下import形式之一来导入其它模块中的导出内容:

  1. 导入一个模块中的某个导出内容,也可对于进行重命名::
    格式如下:
    import { 要导出的内容的名字 } from "模块路径";
    import { 要导出的内容的名字 as 新名字 } from "模块路径";
    
    示例如下:
    import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
    let myValidator = new ZCV();
    
  2. 将整个模块导入到一个变量,并通过它来访问模块的导出部分:
    格式如下:
    import * as 新名字 from "模块路径";
    
    示例如下:
    import * as validator from "./ZipCodeValidator";
    let myValidator = new validator.ZipCodeValidator();
    
  3. 导出默认的导出项:
    每个模块都可以有一个default导出。 默认导出使用default关键字标记;并且一个模块只能够有一个default导出。
    导出默认的导邮项目的格式如下:
    import 自定义名字 from "模块路径";
    
    示例如下:
    import JQ from "JQuery";
    
    JQ("button.continue").html( "Next Step..." );
    
  4. 具有副作用的导入模块:
    格式如下:
    import "模块路径";
    
    此种导入,相当于把相应模块的代码插入到了本模块;

export = 和 import = require()

CommonJS和AMD都有一个exports对象的概念,它包含了一个模块的所有导出内容。
它们也支持把exports替换为一个自定义对象。 默认导出就好比这样一个功能;然而,它们却并不相互兼容。 TypeScript模块支持export =语法以支持传统的CommonJS和AMD的工作流模型。
export =语法定义一个模块的导出对象。 它可以是类,接口,命名空间,函数或枚举。
若要导入一个使用了export =的模块时,必须使用TypeScript提供的特定语法import module = require("module")。
示例如下:
ZipCodeValidator.ts

let numberRegexp = /^[0-9]+$/;
class ZipCodeValidator {
    isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
    }
}
export = ZipCodeValidator;

Test.ts

import zip = require("./ZipCodeValidator");

// Some samples to try
let strings = ["Hello", "98052", "101"];

// Validators to use
let validator = new zip();

// Show whether each string passed each validator
strings.forEach(s => {
  console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`);
  });

2. 别名

格式:

import 新名字 = x.y.z;

这是一种简化命名空间操作的方法是使用import q = x.y.z给常用的对象起一个短的名字。 不要与用来加载模块的import x = require('name')语法弄混了,这里的语法是为指定的符号创建一个别名。 你可以用这种方法为任意标识符创建别名,也包括导入的模块中的对象。
示如如下:

namespace Shapes {
    export namespace Polygons {
            export class Triangle { }
     export class Square { }
    }
}

import polygons = Shapes.Polygons;
let sq = new polygons.Square(); // Same as "new Shapes.Polygons.Square()"

注意:
我们并没有使用require关键字,而是直接使用导入符号的限定名赋值。 这与使用var相似,但它还适用于类型和导入的具有命名空间含义的符号。 重要的是,对于值来讲,import会生成与原始符号不同的引用,所以改变别名的var值并不会影响原始变量的值。


3. 函数语法

  1. 函数类型的表示:
    (参数列表)=>返回值类型
    
  2. 函数的定义:
    function 函数名字(参数列表):返回类型 {
        代码
    }
    
  3. 箭头函数的定义:
    (参数列表):返回类型=>{
        代码
    }
    

4. TypeScript语法特性:

  1. TypeScript的类型注释是可选的,可有可无;并且TypeScript编译器具有类型推断功能;
  2. 函数的参数列表中的可选参数必须放在必须参数的后面;
  3. 函数的参数列表中的默认参数值参数不必非得放在必须参数的后面,它可以放在参数列表的任何位置;当默认值参数不是放在必须参数的后面时,用户必须通过给默认值参数传入undefined来使用默认值参数的默认值;当默认参值参数放在必须参数后面时,默认值参数是可选的,在调用函数时,可以省略默认值参数;
  4. 剩余参数必须是数组类型,并且必须放在能数列表中的最后一个;
  5. 在TypeScript里,类的成员默认为public;
  6. 只读属性必须在声明时或构造函数里被初始化;
  7. 使用存取器时,编译器必须设置为输出ECMAScript 5或更高;不支持降级到ECMAScript 3;
  8. 只带有get不带有set的存取器自动被推断为readonly;这在从代码生成.d.ts文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值;

5. 接口

  1. 当把对象字面量赋值给变量或作为参数传递的时候,该对象字面量不能存在任何“目标类型”(变量类型或者参数类型)不包含的属性时;
  2. 对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,009评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,808评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,891评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,283评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,285评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,409评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,809评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,487评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,680评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,499评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,548评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,268评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,815评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,872评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,102评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,683评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,253评论 2 341

推荐阅读更多精彩内容