目录
正文开始
,如果觉得文章对您有帮助,请帮我三连+订阅,谢谢
💖💖💖
typescript 与 babel 区别
编译
TypeScript 早已能像 Babel 一样输出 ES5 代码,可通过将 target 设置为 ES5 或 ES6 来实现。但 Babel 配置通过
@babel/preset-env
改进了这方面功能。你可以列出需要支持的环境,而不是锁定一组特定的 JavaScript 功能(ES5,ES6 等)
Babel 是超级可配置的
想要 JSX? Flow?TypeScript?只需安装一个插件,Babel 就可以处理它。有大量的 官方插件,主要涵盖即将推出的 JavaScript 语法。
编译器
ts 需要用自己的 tsc ,tsc 不支持很多还在草案阶段的语法,这些语法都是通过 babel 插件来支持的
babel 下一代的 js 编译器,无论你的代码是否具有 ES2015、JSX、TypeScript 都能编译
模块
TypeScript 1.5 里术语名已经发生了变化。 “内部模块”现在称做“命名空间”。 “外部模块”现在则简称为“模块”,也就是说
module X { 相当于现在推荐的写法 namespace X {)。
任何包含顶级 import 或者 export 的文件都被当成一个模块。相反地,如果一个文件不带有顶级的 import 或者 export 声明,那么它的内容被视为全局可见的
- 为了支持 CommonJS 和 AMD 的 exports, TypeScript 提供了
export =
语法。 - 若使用
export =
导出一个模块,则必须使用 TypeScript 的特定语法import module = require("module")
来导入此模块。
// 外部模块
declare module '*vue' {
import Vue from 'vue'
export default Vue
}
declare module "*.scss";
// 全局模块
// 默认.d.ts 的内容就是全局的, 模块下的想全局, 必须得 import export 去标识模块
declare global {
function hello2(s: string): void
namespace JSX {
export interface Element {}
}
}
export {} // 使文件模块化
模块解析规则
// A.ts 文件路径: /root/src/folder/A.ts
import { b } from "moduleB"
//去寻找声明的路径
/root/src/folder/moduleB.ts
/root/src/folder/moduleB.d.ts
/root/src/moduleB.ts
/root/src/moduleB.d.ts
/root/moduleB.ts
/root/moduleB.d.ts
/moduleB.ts
/moduleB.d.ts
命名空间
使用命名空间(之前叫做“内部模块”)来组织你的代码,让代码提示性更好,主要体现组织代码
例如验证器、 D3
namespace Validate {
export interface BooleanValidate {}
}
namespace Validate {
export interface StringValidate {}
}
declare let vv: Validate.StringValidate
// 实例代码
let v3 : Validate.StringValidate = {}
let v4 : typeof vv = {}
interface 合并逻辑
声明合并
interface Cloner {
clone(animal: Animal): Animal
clone(animal: Dog): Animal
}
interface Cloner {
clone(animal: Sheep): Sheep
}
// 结果
interface Cloner {
clone(animal: Sheep): Sheep // 后来的具有最高优先级
clone(animal: Animal): Animal
clone(animal: Dog): Animal
}
普通项目怎么从 js 迁移到 ts
tsc --init
, 生成tsconfig.json
- 配置
tsconfig.json
, allowJs 、 outDir, 上线就用 outDir 里的文件 - 将文件的后缀修改为
.ts .tsx
解决冲突
- 增加一些声明文件
// xx.d.ts
declare function require(path: string): any;
- 配合配置文件中的 module 属性,修改模块导入导出
// commonjs
var foo = require("foo");
foo.doStuff();
// requirejs
define(["foo"], function(foo) {
foo.doStuff();
})
// 全部换成 ts的模块导入
import foo = require("foo");
foo.doStuff();
- 获取一些库的
@types
:@types/lodash
第三方工具生成.d.ts
文件
// 整包生成
npm install -g dts-gen // 先全局安装dts-gen
npm install -g yargs // 然后在全局安装你需要生产声明文件的库
dts-gen -m yargs // 执行命令生成文件
// 单文件生成
npm i dtsmake -g // 先全局安装dtsmake
dtsmake -s ./path/to/sourcefile.js // 在对应的文件生产文件
三斜线指令
三斜线指令仅可放在包含它的文件的最顶端
它用于声明文件间的 依赖。告诉编译器在编译过程中要引入的额外的文件
/// <reference path="..." /> 标识依赖路径
/// <reference types="..." /> 声明了对某个包的依赖。
例如,把 /// <reference types="node" />引入到声明文件,表明这个文件使用了 @types/node/index.d.ts里面声明的名字; 并且,这个包需要在编译阶段与声明文件一起被包含进来。仅当在你需要写一个d.ts文件时才使用这个指令。
模块解析逻辑
两种模式: classic && Node
classic :
相对:在当前路径下找 .ts .d.ts
非相对: 一层一层的向上找 .ts .d.ts
node:
node本身查找原理:
相对:
1. 当前给的路径找 .js 后缀结尾的文件
2. 路径下找 package.json -> main 属性
3. 路径下是否有index.js
非相对:
从当前一层一层的向上查找(node_modules)是否有这个文件
typescript原理:
1. 后缀:.ts .tsx .d.ts
2. package.json -> types/typings 属性
3. 查找方式就是 1+2+ 模式
types 发布
1.与你的npm包捆绑在一起,或
2.发布到npm上的@types organization。
注意"typings"与"types"具有相同的意义,也可以使用它。
dependencies or devDependencies?
如果我们只是在写一个命令行应用,并且我们的包不会被当做一个库使用的话,那么我就可以使用 devDependencies。
3.不要在声明文件里使用/// <reference path="..." />。
应该使用/// <reference types="..." />代替
书写 ts 的声明文件
1.全局变量
2.全局函数
3.带属性的对象 namespace
4.函数重载 // 声明多个签名不一样的函数
5.可重用类型(接口) // 必填/选填 属性
6.可重用类型(类型别名) // 接受 字符串 / 函数返回字符串 / 一个实例对象
type GreetingLike = string | (() => string) | MyGreeter;
declare function greet(g: GreetingLike): void;
7.组织类型 + 类
// 声明
declare namespace GreetingLib {
interface LogOptions {
verbose?: boolean
}
interface AlertOptions {
modal: boolean
title?: string
color?: string
}
}
declare class Greeter {
constructor (s: string)
log: (val: GreetingLib.LogOptions) => void
alert: (val: GreetingLib.AlertOptions) => void
}
Property ‘includes’ does not exist on type ‘number[]’
当 tsc 后面跟文件的时候,不会 使用 tsconfig.json
global 申明
// declare global
+ 在 d.ts 声明文件中,任何的 declare 默认就是 global 的了,所以你在 d.ts 文件中是不能出现 declare global 的。
+ 只有在模块文