typescript 笔记2
typescript 学习笔记2
模块 导出/导入
/**
* 导出
**/
// 当前文件有 export 内容,所以当前文件会被当成一个模块,
// 内部申明的变量不能直接被全局访问;
const modStr: string = "abc";
const expBol: boolean = true;
// 可以导出多种类型
export const expStr: string = "export";
export interface IExp {
num: number;
}
export class CExp {
str: string = "abc";
}
export type StrOrNum = string | number;
// 先申明后导出
export { expBol };
// 可以直接引导出引入的变量,进行重命名或拓展
// 也可以自己引入自己的变量
export { expBol as expBol2 } from "./export";
// 被直接导出的导入变量,当前模块代码无法访问
// expBol2; // Error
/**
* 默认导出
*
* 一个模块只能有一个默认导出
*/
const bol: boolean = true;
export default bol;
// 不能这样简写(申明即导出)
// export default const bol = true; // Error
// 但是 类、函数、接口 等可以申明即导出
// export default class CS {}
// export default function() {}
// export default interface IF {}
// 字面值也可以直接默认导出
// export default true
// export default 'abc';
// export default 123;
// export default { num: 123 };
/**
* 导入
**/
// ts 文件中不带顶级的 import 或 export,
// 则内部申明的变量默认全局可访问;
num; // from advanceType.ts
num1; // from basicType.ts
// 无法直接访问具有 export 申明的 export.ts 文件(模块)中的变量
// modStr; // Error
// 导入需要加上路径,文件名后缀可省略
import { expStr, IExp, CExp, expBol, expBol2 } from "./export";
// 导入具有默认导出的模块,可以对默认内容重命名
import renamedBol from "./defaultExport";
// 导入模块所有内容到一个变量(对象)中
import * as exportObj from "./export";
// 导入类型变量的语法
import type { StrOrNum } from './export';
// 没有 export 的内容,也能直接通过 import './global' 的形式,
// 引入当前文件中的所有全局变量
const globalVar1: string = 'abc';
// 直接导入文件(没有包含 export),使引入文件中的所有全局变量
// 在当前文件可访问,例如:globalVar1
import "./global";
// 导入 export = xxx 形式的导出模块
import bol1 = require("./defaultExport");
let str: string = expStr;
str = globalVar1;
let bol: boolean = expBol;
bol = expBol2;
bol = renamedBol;
bol = exportObj.expBol2;
bol = bol1;
let obj1: IExp = {
num: 123,
};
class CS1 extends CExp {}
let str2: StrOrNum = 'abc';
// 动态导入模块
// 首先申明 require 函数,或者直接安装申明文件:npm i -D @types/node
declare function require(name: string): any;
let bol2: boolean;
if (Math.random() > 0.5) {
bol2 = require('./global');
} else {
bol2 = false;
}
bol = bol2;
/**
* 模块解析过程
*/
// 导入模块示例:
// import * from 'test';
// 相对导入:
// 带有路径标识,例如:'./test', '/test', '../test';
// 非相对导入:
// 不带路径标识,例如:'test', 'test/test', '@test/test';
// 相对导入:
// import * from './test'; 的解析模块文件顺序:
//
// ./test.ts
// ./test.tsx
// ./test.d.ts
// ./test/package.json (如果文件有指定 "types" 属性,则取它的值对应的文件)
// ./test/index.ts
// ./test/index.tsx
// ./test/index.d.ts
// 非相对导入:
// import * from 'test'; 的解析模块文件顺序
//
// ./node_modules/test.ts
// ./node_modules/test.tsx
// ./node_modules/test.d.ts
// ./node_modules/test/package.json (如果文件有指定 "types" 属性,则取它的值对应的文件)
// ./node_modules/test/index.ts
// ./node_modules/test/index.tsx
// ./node_modules/test/index.d.ts
// ...(依次寻找上一级目录的 node_modules 文件夹)
// 配置文件中指定如何 解析非相对模块:
// {
// "compilerOptions": {
// "baseUrl": ".",
// "paths": {
// "test": [
// "test/test", // 这里路径是相对于上面的 "baseUrl" 属性值
// "test1/test1", // 可以指定多个回退路径,文件不存在会依次解析下一个
// "*" // 模块名称与文件相同(当前路径下)可以直接使用通配符
// ]
// }
// }
// }
命名空间
// ts 1.5 之后,内部模块(module x {})改为 命名空间(namespace x {}),
// 外部模块 改为 模块(import/export)
// 当前文件中或与其他文件中的全局变量中,存在重复的变量名申明会报错
// let num; // Error
let num7: number;
// let num7; // Error
// 通过命名空间解决这个问题
namespace Name1 {
let num: number = 1;
}
namespace Name2 {
// 同时,其他文件中也能这样重新申明同名变量;
let num: number = 1;
}
// 但是变量和接口名可以重复,分别表示不同的结构
let CommonName;
interface CommonName {};
// 类、接口、命名空间也可以名称相同,都表示为同一个类型结构
class CommonName1 {};
interface CommonName1 {};
namespace CommonName1 {};
/**
* 命名空间 嵌套
*/
namespace Name3 {
namespace Name3_1 {
let num: number = 1;
}
namespace Name3_2 {
let num: number = 2;
}
// 变量之间互不影响
let num: number = 3;
}
// 内部嵌套的命名空间外部无法访问
// Name3_1; // Error
/**
* 命名空间 别名
*/
namespace Name4 {
export namespace Name4_1 {
export namespace Name4_2 {
export const num: number = 1;
}
}
}
// 取别名的格式为:import xxx = name1.name2 ...
import Name42 = Name4.Name4_1.Name4_2;
// 访问别名中的变量就像访问对象
let num10: number = Name42.num;
/**
* 外部命名空间
*/
declare namespace Name5 {
export type num = number;
}
declare let num11: Name5.num;
发布
/************************************************************
* 发布
*
* 发布声明文件的方式:
* - 包含到 npm 包中;
* - 发布到 @types 组织上
************************************************************/
/**
* 包含到 npm 包中
*
* 使用该 npm 包时可以不用添加额外的声明依赖("@types/xxx")到 "dependencies" 中
*/
// 配置 package.json 中的 "types" 属性(或者 "typings"),添加声明文件入口:
// {
// "name": "demo",
// "version": "0.1.1",
// "main": "./src/main.ts",
// "types": "./src/main.d.ts"
// }
//
// "main","types" 文件都有导出的话,最终只会导出 "types" 中的内容,
// 否则只会导出配置了的那个文件的导出内容;
//
// 只有声明入口文件和 "main" 文件同级并且同名(后缀 ".d.ts"),
// 才可以不用配置 "types" 值,ts 会自动识别它为声明文件入口;
// 也可以指定某些 ts 版本下使用的声明文件来源:
// {
// "typesVersions": {
// ">=3.1": {
// "*": ["ts3.1/*"]
// }
// ">=3.0": {
// "*": ["ts3.0/*"]
// }
// }
// }
// 该配置表示如果当前使用的 ts 版本大于等于 3.1 时,将从 "ts3.1"(与 package.json 文件同级)目录中读取声明文件,
// 然后是判断 3.0 版本,最后如果都没有匹配的,则再从 "types" 中读取声明文件;
// 注意版本的书写顺序,应该是高版本在上,低版本在下,否则会匹配错误;
/**
* 发布到 @types 公共仓库中
*/
// 要单独发布自己的包对应的 types 包,先提交 PR 到 <https://github.com/DefinitelyTyped/DefinitelyTyped> 仓库中,
// types 包名称需要 npm 包对应,比如 demo 包对应的 types 包应该是 @types/demo;
// 然后使用发布工具 <https://github.com/microsoft/DefinitelyTyped-tools/tree/master/packages/publisher> 将 types 包发布到 npm 上;