typescript声明空间-学习笔记

1,203 阅读4分钟

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