typescript声明空间-学习笔记
声明空间
类型声明空间
class Foo {}
interface Bar {}
type Bas = {};
// 类型注解
let foo:Foo;
let bar:Bar;
let bas:Bas;
// “Bar”仅表示类型,但在此处却作为值使用,以下语法是错误的,不能将Bar在interface的情况下赋值给bar
// const bar = Bar;
变量声明空间
class Foo {}
// 这里把一个类当做变量来使用,前面的则是interface后直接赋值报错
const someVar = Foo;
const someOtherVar = 123;
// 相反的则有如果直接像var定义或者是const去定义变量则也不能使用类型注解,例如:
const foo = 123;
let bar:foo;// 找不到名称“foo”。
模块
全局模块
foo.ts
const foo =123;
bar.ts
// 这样写是被允许的,而如果是定义fo则不行,因此在全局中foo能够在当前的项目中被找到,而fo则不行
const bar = foo;
文件模块
文件模块区别于全局模块则是利用了export和import这两个导出和导入的方法;
我们来改写下上面的代码,优先改写下foo.ts文件,如下:
export const foo =123;
在写完这个文件后,我们再回过头来查看bar.ts,在这个时候,bar文件已经开始报错,提示找不到foo这个文件,这个时候,我们需要利用import来引入foo.ts中foo这个值来赋予bar,如下:
import { foo } from './foo.ts'
const bar = foo;
这样定义后不会污染全局命名空间
文件模块详情
- AMD: 不要使用,只能在浏览器工作;
- SystemJS: 这是一个好实验?已经被ES模块替代;
- ES模块: 没有准备好?莫名其妙。。。
使用module:commonjs选项来替代楼上这些模式,突然来了一句
import foo = require('foo')
ES模块
foo.ts
- export写法一
// 定义变量
export const someVar = 123;
// 定义类型
export type someType = {
foo:string
}
- export写法二
// 定义变量
const someVar = 123;
// exprot {someVar as aDifferentName};重命名变量someVar再传递,再另一边import出来的应为名为aDifferentName
// 定义类型
type someType = {
foo:string
}
exprot {someVar,someType};
bar.ts
在这个文件中,我们可以导入foo.ts写入的变量,代码如下:
// 变量或者类型都可以通过这样导入
import {someVar,someType} from './foo';
楼上有export的时候去改变名字再传,现在在import进来的时候也可以进行名称的更改,代码如下:
import {someVar as aDifferentName} from './foo';
导出所有foo.ts中的导出的值,无论是变量还是定义的类型,写法如下:
import * as foo from './foo';
其他的导入方式
// 仅导入模块
import 'core-js';// 一个普通的polyfill库
// 从其他模块导入后整体导出
export * from './foo';
// 从其他模块导入后,部分导出:
export {someVar} from './foo';
// 通过重命名,部分导出从另一个模块导入的项目:
export {someVar as aDifferentName} from './foo';
- 默认导出的写法,
变量不需要加let/const/var
export default (someVar = 123);
exprot default function someFuntion() {}
export default class someClass {}
模块路径
在TypeScript配置文件中,如果我们使用了module:commonjs选项,moduleResolution:node 默认开启
模块路径分两种,动态查找,相对路径模块
相对路径就是以.开头,动态则是如楼上core-js,something/foo,动态路径查找是模块解析会模仿Node模块解析策略,会直接查找到根目录;
重写类型的动态查找
declare module 'somePath'来声明一个全局模块的方式,解决查找模块路径的问题,写在global.d.ts这个文件中;
declare module 'foo' {
// some variable declarations
export var bar: number;
}
import/require 仅仅是导入类型
从代码层面来说,import和require都是引入代码块或者变量等,在ts语法上,最终需要被编译成js,因此,
- 有时候引入了没用,ts文件会编译成空文件;
import foo = require('foo');//编译为空
- 类型注解,会编译为定义了变量没引用;
// 像这种导入后进行类型注解,其实只是定义了变量
import foo = require('foo');
var bar: foo;
//最终编译为如下的代码:
let bar;//foo没有被当成一个变量使用
- 引入并且赋值给js变量或者使用了,则会编译出来;
import foo = require('foo');
const bar = foo;
//编译如下:
const foo = require('foo');
const bar = foo;//这里的foo当做变量赋值给了bar