首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将多个声明文件和文件夹贡献给DefinitelyTyped

如何将多个声明文件和文件夹贡献给DefinitelyTyped
EN

Stack Overflow用户
提问于 2018-01-03 04:44:47
回答 1查看 453关注 0票数 1

我已经为PlayCanvas游戏引擎编写了TypeScript声明文件。源代码在pc名称空间下有一个全局结构。在编写声明文件时,我复制了源代码的文件和文件夹结构。我有超过50个独立的d.ts文件,它们都使用declare namespace pc {}。我现在想把这些声明文件贡献给DefinitelyTyped,但是看一下文档,他们似乎想要所有的东西都放在一个叫做index.d.ts文件的大文件中。我怎样才能转换我的所有文件和文件夹,使整个东西与DefinitelyTyped兼容?我真的需要把所有的东西都塞到一个文件里吗?我不能只保留我漂亮的文件和文件夹结构来匹配引擎的源代码吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-03 06:06:58

这是为大型库创建类型定义的常见痛点。此时最好的解决方案是使用诸如dts-generator之类的实用程序来生成index.d.ts以供分发/使用(并将您的单个文件/文件夹作为源)。

dts生成器半盲目地将所有内容转储到一个文件中。在我的例子中(碰巧也是一个游戏引擎,你可以看到here),这个文件需要一些后处理才能与我的index.ts文件兼容,该文件重新导出库的不同部分。这是一个可以与ts-node (npm i ts-node -g)一起运行的命令行实用程序。

代码语言:javascript
复制
import * as fs from 'fs';
import * as readline from 'readline';

const moduleDeclaration = 'module-typings.d.ts'; // file created by dts-generator
const indexDeclartion = 'index.d.ts';
const distPath = './dist/';

const indexOut: string[] = [];

const reader = readline.createInterface({
    input: fs.createReadStream(`${distPath}${moduleDeclaration}`),
});

const moduleDeclaration = /^declare module/;
const malletImport = /(import|export).+from 'mallet/;

function isExcluded(line: string) {
    return moduleDeclaration.exec(line) || malletImport.exec(line) || line === '}';
}

const identifiers = [];
const importLine = /import {(.*)} (.*)/;
const importRequire = /import (.*) = (.*)/;
function stripDuplicateDeclarations(line) {
    let importResult;
    if ((importResult = importLine.exec(line))) { // tslint:disable-line:no-conditional-assignment
        const imports = importResult[1].replace(/\s/g, '').split(',');
        const newImports = imports.filter((variable) => identifiers.indexOf(variable) === -1);
        Array.prototype.push.apply(identifiers, newImports);
        const importString = newImports.join(', ');
        return line.replace(importLine, `import {${importString}} $2`);
    } else if ((importResult = importRequire.exec(line))) { // tslint:disable-line:no-conditional-assignment
        const importName = importResult[1];
        if (identifiers.indexOf(importName) === -1) {
            identifiers.push(importName);
            return line;
        }

        return ''; // return an empty line if the import exists
    }

    return line;
}

const constLine = /^\s{2}const .+:/;
function declareConst(line) {
    if (constLine.exec(line) !== null) {
        return (`declare${line}`).replace(/\s+/, ' ');
    }

    return line;
}

reader.on('line', (line) => {
    if (!isExcluded(line)) {
        const finalLine = [stripDuplicateDeclarations, declareConst]
            .reduce((processedLine, processor) => processor(processedLine), line);
        indexOut.push(finalLine);
    }
});

reader.on('close', () => {
    const indexContext = indexOut.join('\n');
    fs.writeFileSync(`${distPath}${indexDeclartion}`, indexContext, {encoding: 'utf-8'});
});

这个脚本去掉了重复的声明和嵌套的命名空间,因此使用者可以轻松地导入库组件。作为免责声明,此脚本只是一个适用于我的库的示例,并不打算处理所有情况。可能有一种更正确(也更复杂)的方法来使用TypeScript应用程序接口来完成这类处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48067611

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档