好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

怎么实现自动生成typescript类型声明工具

本篇内容主要讲解“怎么实现自动生成typescript类型声明工具”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么实现自动生成typescript类型声明工具”吧!

在TypeScript 项目中,我们经常需要使用声明一系列的ts类型。然而,手动写的效率实在太低,编写一个自动生成ts类型的工具可以解放生产力。 实现一个工具将 JSON 数据转换为 TypeScript 类型定义,从而让 TypeScript 项目更高效的开发。

一、实现的功能

将 JSON 数据转换为 TypeScript 类型定义。

支持嵌套的复杂类型,如数组和对象。

支持自定义类型名称和命名空间。

支持将转换后的 TypeScript 类型定义保存为文件。

二、工具使用方法

1.在线playground使用:在线json转ts类型声明

2.已经发布到npm:my-json-to-ts - npm (npmjs测试数据)

运行效果如下动图:

安装工具:

npm?install?-g?my-json-to-ts

运行工具:

my-json-to-ts?input.json?output.ts

其中 input.json 是要转换的 JSON 文件路径, output.ts 是转换后的 TypeScript 文件路径。

--name?类型名称????#?指定转换后的类型名称,默认为?JsonType
--namespace?命名空间?#?指定转换后的命名空间,默认为无
--no-file??????????#?不将转换后的?TypeScript?类型定义保存为文件

三、实现思路

读取输入的 JSON 文件,解析成 JSON 对象。

遍历 JSON 对象,根据不同的类型生成对应的 TypeScript 类型定义字符串。

如果指定了类型名称和命名空间,则在生成的 TypeScript 类型定义字符串前面添加对应的声明。

如果指定了保存文件,则将生成的 TypeScript 类型定义字符串写入文件。

四、使用示例

以下是将JSON 数据和转换后的 TypeScript 类型定义示例:

简单的JSON 数据
{
??"name":?"John",
??"age":?30,
??"address":?{
????"city":?"New?York",
????"state":?"NY"
??},
??"hobbies":?[
????"reading",
????"traveling"
??]
}
输出对应简单的类型定义
interface?JsonType?{
??name:?string;
??age:?number;
??address:?{
????city:?string;
????state:?string;
??};
??hobbies:?string[];
}
复杂的JSON 数据
{
??"name":?"John",
??"age":?30,
??"address":?{
????"city":?"New?York",
????"state":?"NY",
????"postalCode":?10001
??},
??"friends":?[
????{
??????"name":?"Jane",
??????"age":?28,
??????"address":?{
????????"city":?"Los?Angeles",
????????"state":?"CA"
??????}
????},
????{
??????"name":?"Bob",
??????"age":?35,
??????"address":?{
????????"city":?"Chicago",
????????"state":?"IL"
??????}
????}
??],
??"hobbies":?[
????"reading",
????"traveling",
????{
??????"name":?"swimming",
??????"location":?"pool"
????}
??]
}
输出对应复杂类型定义
interface?JsonType?{
??name:?string;
??age:?number;
??address:?{
????city:?string;
????state:?string;
????postalCode:?number;
??};
??friends:?{
????name:?string;
????age:?number;
????address:?{
??????city:?string;
??????state:?string;
????};
??}[];
??hobbies:?(string?|?{
????name:?string;
????location:?string;
??})[];
}

五、具体实现代码

首先引入两个 Node.js 模块: fs-extra 和 commander 。 fs-extra 是一个简化了 Node.js 文件系统模块的封装,而 commander 是一个命令行工具的库,可以方便地解析命令行参数。

接下来定义一个函数 jsonToTs ,用于将 JSON 数据转换为 TypeScript 类型定义字符串。该函数采用递归的方式遍历 JSON 数据,生成对应的 TypeScript 类型定义。如果 JSON 数据是数组,则递归处理其中的每个元素;如果是对象,则递归处理其中的每个属性。最终,该函数返回一个 TypeScript 类型定义字符串。

然后定义了两个异步函数, readJson 和 writeTs ,分别用于读取 JSON 文件和将 TypeScript 类型定义字符串写入文件。

最后定义一个名为 jsonToTsFile 的函数,该函数接收命令行参数并将其传递给 jsonToTs 函数,然后将生成的 TypeScript 类型定义字符串保存到文件中。如果命令行参数中指定了不保存文件,则该函数将直接将 TypeScript 类型定义字符串输出到控制台。

??const?fs?=?require('fs-extra');
??const?commander?=?require('commander');
??/**
???*?将?JSON?数据转换为?TypeScript?类型定义
???*?@param?{Object}?object?-?要转换的?JSON?对象
???*?@param?{string}?[name=JsonType]?-?转换后的类型名称
???*?@param?{string}?[namespace]?-?转换后的命名空间
???*?@returns?{string}?-?转换后的?TypeScript?类型定义字符串
???*/
??function?jsonToTs(object,?name?=?'JsonType',?namespace)?{
??????const?getType?=?value?=>?{
??????????let?typeRes?=?``;
??????????if?(Array.isArray(value))?{
??????????????value.forEach(item?=>?{
??????????????????let?subType?=?getType(item);
??????????????????if?(typeRes.split('|').indexOf(subType)?<?0)?{
??????????????????????typeRes?+=?subType
??????????????????????typeRes?+=?"|"
??????????????????}
??????????????})
??????????????typeRes?=?typeRes.substring(0,?typeRes.length?-?1)
???????????????if?(typeRes.split('|').length?>?1)?{
??????????????????return?`(${typeRes})[]`;
????????????????}?else?{
??????????????????return?`${typeRes}[]`;
????????????????}
??????????}
??????????if?(typeof?value?===?'object'?&&?value?!==?null)?{
??????????????const?props?=?Object.entries(value)
??????????????????.map(([key,?val])?=>?`${key}:?${getType(val)}`)
??????????????????.join(';?');
??????????????return?`{?${props}?}`;
??????????}
??????????return?typeof?value;
??????};
??????const?type?=?getType(object);
??????const?declaration?=?`interface?${name}?${type}`;
??????return?namespace???`namespace?${namespace}?{?\r\n?${declaration}?\r\n}`?:?declaration;
??}
??/**
???*?读取文件并解析成?JSON?对象
???*?@param?{string}?path?-?文件路径
???*?@returns?{Promise<Object>}?-?JSON?对象
???*/
??async?function?readJson(path)?{
??????const?content?=?await?fs.readFile(path,?'utf8');
??????return?JSON.parse(content);
??}
??/**
???*?将?TypeScript?类型定义字符串写入文件
???*?@param?{string}?content?-?TypeScript?类型定义字符串
???*?@param?{string}?path?-?文件路径
???*?@returns?{Promise<void>}
???*/
??async?function?writeTs(content,?path)?{
??????await?fs.writeFile(path,?content,?'utf8');
??}
??/**
???*?将?JSON?数据转换为?TypeScript?类型定义
???*?@param?{string}?inputPath?-?输入?JSON?文件路径
???*?@param?{string}?outputPath?-?输出?TypeScript?文件路径
???*?@param?{string}?[options.name=JsonType]?-?转换后的类型名称
???*?@param?{string}?[options.namespace]?-?转换后的命名空间
???*?@param?{boolean}?[options.noFile]?-?不将?TypeScript?类型定义保存为文件
???*?@returns?{Promise<void>}
???*/
??async?function?jsonToTsFile(inputPath,?outputPath,?options)?{
??????const?{?name,?namespace,?noFile?}?=?options
??????try?{
??????????const?object?=?await?readJson(inputPath);
??????????const?type?=?jsonToTs(object,?name,?namespace);
??????????if?(noFile)?{
??????????????console.log(type);
??????????}?else?{
??????????????await?writeTs(type,?outputPath);
??????????????console.log(`Type?definition?saved?to?${outputPath}`);
??????????}
??????}?catch?(err)?{
??????????console.error(err.message);
??????}
??}
??const?program?=?new?commander.Command();
??program
??????.arguments('<input>?<output>')
??????.option('--no-file',?'do?not?save?to?file')
??????.option('-s,?--namespace?<namespace>',?'type?namespace')
??????.option('-n,?--name?<name>',?'type?name',?'JsonType')
??????.action(jsonToTsFile);
??program.parse(process.argv);

到此,相信大家对“怎么实现自动生成typescript类型声明工具”有了更深的了解,不妨来实际操作一番吧!这里是***网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

查看更多关于怎么实现自动生成typescript类型声明工具的详细内容...

  阅读:55次