自動(dòng)生成typescript類型聲明工具實(shí)現(xiàn)詳解
在TypeScript 項(xiàng)目中,我們經(jīng)常需要使用聲明一系列的ts類型。然而,手動(dòng)寫的效率實(shí)在太低,編寫一個(gè)自動(dòng)生成ts類型的工具可以解放生產(chǎn)力。 實(shí)現(xiàn)一個(gè)工具將 JSON 數(shù)據(jù)轉(zhuǎn)換為 TypeScript 類型定義,從而讓 TypeScript 項(xiàng)目更高效的開發(fā)。
一、實(shí)現(xiàn)的功能
- 將 JSON 數(shù)據(jù)轉(zhuǎn)換為 TypeScript 類型定義。
- 支持嵌套的復(fù)雜類型,如數(shù)組和對(duì)象。
- 支持自定義類型名稱和命名空間。
- 支持將轉(zhuǎn)換后的 TypeScript 類型定義保存為文件。
二、工具使用方法
1.在線playground使用:在線json轉(zhuǎn)ts類型聲明
2.已經(jīng)發(fā)布到npm:my-json-to-ts - npm (npmjs.com)
運(yùn)行效果如下動(dòng)圖:

安裝工具:
npm install -g my-json-to-ts
運(yùn)行工具:
my-json-to-ts input.json output.ts
其中 input.json 是要轉(zhuǎn)換的 JSON 文件路徑,output.ts 是轉(zhuǎn)換后的 TypeScript 文件路徑。
--name 類型名稱 # 指定轉(zhuǎn)換后的類型名稱,默認(rèn)為 JsonType --namespace 命名空間 # 指定轉(zhuǎn)換后的命名空間,默認(rèn)為無(wú) --no-file # 不將轉(zhuǎn)換后的 TypeScript 類型定義保存為文件
三、實(shí)現(xiàn)思路
- 讀取輸入的 JSON 文件,解析成 JSON 對(duì)象。
- 遍歷 JSON 對(duì)象,根據(jù)不同的類型生成對(duì)應(yīng)的 TypeScript 類型定義字符串。
- 如果指定了類型名稱和命名空間,則在生成的 TypeScript 類型定義字符串前面添加對(duì)應(yīng)的聲明。
- 如果指定了保存文件,則將生成的 TypeScript 類型定義字符串寫入文件。
四、使用示例
以下是將JSON 數(shù)據(jù)和轉(zhuǎn)換后的 TypeScript 類型定義示例:
??簡(jiǎn)單的JSON 數(shù)據(jù)
{
"name": "John",
"age": 30,
"address": {
"city": "New York",
"state": "NY"
},
"hobbies": [
"reading",
"traveling"
]
}
??輸出對(duì)應(yīng)簡(jiǎn)單的類型定義
interface JsonType {
name: string;
age: number;
address: {
city: string;
state: string;
};
hobbies: string[];
}
?復(fù)雜的JSON 數(shù)據(jù)
{
"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"
}
]
}
?輸出對(duì)應(yīng)復(fù)雜類型定義
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;
})[];
}
五、具體實(shí)現(xiàn)代碼
首先引入兩個(gè) Node.js 模塊:fs-extra 和 commander。fs-extra 是一個(gè)簡(jiǎn)化了 Node.js 文件系統(tǒng)模塊的封裝,而 commander 是一個(gè)命令行工具的庫(kù),可以方便地解析命令行參數(shù)。
接下來(lái)定義一個(gè)函數(shù) jsonToTs,用于將 JSON 數(shù)據(jù)轉(zhuǎn)換為 TypeScript 類型定義字符串。該函數(shù)采用遞歸的方式遍歷 JSON 數(shù)據(jù),生成對(duì)應(yīng)的 TypeScript 類型定義。如果 JSON 數(shù)據(jù)是數(shù)組,則遞歸處理其中的每個(gè)元素;如果是對(duì)象,則遞歸處理其中的每個(gè)屬性。最終,該函數(shù)返回一個(gè) TypeScript 類型定義字符串。
然后定義了兩個(gè)異步函數(shù),readJson 和 writeTs,分別用于讀取 JSON 文件和將 TypeScript 類型定義字符串寫入文件。
最后定義一個(gè)名為 jsonToTsFile 的函數(shù),該函數(shù)接收命令行參數(shù)并將其傳遞給 jsonToTs 函數(shù),然后將生成的 TypeScript 類型定義字符串保存到文件中。如果命令行參數(shù)中指定了不保存文件,則該函數(shù)將直接將 TypeScript 類型定義字符串輸出到控制臺(tái)。
const fs = require('fs-extra');
const commander = require('commander');
/**
* 將 JSON 數(shù)據(jù)轉(zhuǎn)換為 TypeScript 類型定義
* @param {Object} object - 要轉(zhuǎn)換的 JSON 對(duì)象
* @param {string} [name=JsonType] - 轉(zhuǎn)換后的類型名稱
* @param {string} [namespace] - 轉(zhuǎn)換后的命名空間
* @returns {string} - 轉(zhuǎn)換后的 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 對(duì)象
* @param {string} path - 文件路徑
* @returns {Promise<Object>} - JSON 對(duì)象
*/
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 數(shù)據(jù)轉(zhuǎn)換為 TypeScript 類型定義
* @param {string} inputPath - 輸入 JSON 文件路徑
* @param {string} outputPath - 輸出 TypeScript 文件路徑
* @param {string} [options.name=JsonType] - 轉(zhuǎn)換后的類型名稱
* @param {string} [options.namespace] - 轉(zhuǎn)換后的命名空間
* @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);
六、寫在最后
這個(gè)工具可以極大地提高在 TypeScript 項(xiàng)目中編寫類型聲明的效率。通過(guò)輸入一個(gè) JSON 數(shù)據(jù),它可以自動(dòng)生成對(duì)應(yīng)的 TypeScript 類型定義,支持復(fù)雜類型,如數(shù)組和對(duì)象,并支持自定義類型名稱和命名空間。此外,還可以選擇將轉(zhuǎn)換后的 TypeScript 類型定義保存為文件。
以上就是自動(dòng)生成typescript類型聲明工具實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于自動(dòng)生成typescript類型聲明的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu)TypeScript之鄰接表實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了數(shù)據(jù)結(jié)構(gòu)TypeScript之鄰接表實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
TypeScript學(xué)習(xí)輕松玩轉(zhuǎn)類型操作
這篇文章主要為大家介紹了TypeScript學(xué)習(xí)輕松玩轉(zhuǎn)類型操作,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
詳解Typescript?嚴(yán)格模式有多嚴(yán)格
這篇文章主要為大家介紹了Typescript?嚴(yán)格模式有多嚴(yán)格實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
數(shù)據(jù)結(jié)構(gòu)TypeScript之棧和隊(duì)列詳解
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)TypeScript之棧和隊(duì)列詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
less簡(jiǎn)單入門(CSS 預(yù)處理語(yǔ)言)
Less 是一門 CSS 預(yù)處理語(yǔ)言,它擴(kuò)充了 CSS 語(yǔ)言,增加了諸如變量、混合(mixin)、函數(shù)等功能,讓 CSS 更易維護(hù)、方便制作主題、擴(kuò)充2017-03-03

