如何从使用export=语句的TypeScript模块导入指定接口?
关于TypeScript中
export=模块的接口导入问题 很多TypeScript类型定义文件会用export=来导出模块,比如这个i40的例子:
declare module "i40" { interface RouterStatic { () : Router; } interface RouteInfo { params : { [key : string] : any; }; splats : string[]; route : string; fn : Function; next : any; } interface Router { addRoute(routeString : string, action ?: Function); match(test : string) :RouteInfo; } export = null as RouterStatic; }
还有人会写这种混合导出的代码,但在TypeScript 2.6及以后版本会编译报错:
export interface Blah {} const x = {hi : 5}; export = x;
编辑说明:这段代码以前可以运行,但在当前版本(2.6)下无法编译,编译器提示如果模块中有其他导出内容则不能使用
export=,这符合逻辑。
现在的问题是:怎么导入这类export=模块里的内部接口?试了下面几种方式都不行:
import Router = require('i40'); let x : Router.RouteInfo; //RouteInfo未找到import {RouteInfo} from 'i40'; //RouteInfo未找到import * as Router2 from 'i40'; //错误,i40不是模块的内容
别着急,咱们分两种情况来解决:
如果你能修改原类型定义文件
这是最直接的办法——把需要外部访问的接口也加上export关键字,同时保留export=的导出:
declare module "i40" { export interface RouterStatic { () : Router; } export interface RouteInfo { params : { [key : string] : any; }; splats : string[]; route : string; fn : Function; next : any; } export interface Router { addRoute(routeString : string, action ?: Function); match(test : string) :RouteInfo; } export = null as RouterStatic; }
改完之后,你就可以灵活导入了:
- 同时导入默认的
RouterStatic和单独的RouteInfo:import Router = require('i40'); import { RouteInfo } from 'i40'; let info: RouteInfo; let router: Router; - 或者用
import *的方式(注意export=的默认导出会放在default属性里):import * as RouterModule from 'i40'; let router: RouterModule.default; let info: RouterModule.RouteInfo;
如果你不能修改原类型定义文件
那咱们就靠TypeScript的类型推导能力来“挖”出内部接口:
import Router = require('i40'); // 先从RouterStatic(一个返回Router的函数)拿到Router类型 type RouterType = ReturnType<Router>; // 再从Router的match方法返回值拿到RouteInfo类型 type RouteInfoType = ReturnType<RouterType['match']>; // 现在就可以用这些类型了 let info: RouteInfoType; let router: RouterType;
这种方式完全不需要改动原文件,通过ReturnType这个工具类型,从已导出的函数类型里反向推导内部的接口类型。
另外提一句那个TS2.6报错的混合导出代码,正确的写法要么把export interface改成内部接口,只保留export=;要么改用ES模块的导出方式(比如export default x; export { Blah };),避免混合使用两种导出语法。
内容的提问来源于stack exchange,提问作者GregRos
相关产品推荐
相关产品推荐

