最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS實現(xiàn)JSON轉(zhuǎn)TypeScript接口的核心步驟

 更新時間:2026年02月24日 09:28:10   作者:滕青山  
這篇文章詳細介紹了如何使用在線工具將JSON數(shù)據(jù)轉(zhuǎn)換為TypeScript接口代碼的全過程,工具通過輸入清洗、JSON解析、類型名生成、類型推斷、對象轉(zhuǎn)聲明文本等步驟,最終生成可讀性強且準確的TypeScript代碼,需要的朋友可以參考下

這篇只講核心 JS 邏輯:一段 JSON 是如何一步步變成 TypeScript 接口代碼的。

在線工具網(wǎng)址:https://see-tool.com/json-to-typescript
工具截圖:

1)狀態(tài)與入口函數(shù)

先看最核心的狀態(tài)和入口:

const jsonInput = ref('')
const outputData = ref('')
const interfaceName = ref('RootObject')
const useType = ref(false)
const optionalProps = ref(true)
const errorMessage = ref('')

const convert = () => {
  const input = jsonInput.value.trim()
  if (!input) {
    outputData.value = ''
    errorMessage.value = ''
    return
  }

  try {
    const parsed = JSON.parse(input)
    if (parsed === null || (typeof parsed !== 'object' && !Array.isArray(parsed))) {
      errorMessage.value = '根節(jié)點必須是對象或數(shù)組'
      outputData.value = ''
      return
    }
    const rootName = interfaceName.value.trim() || 'RootObject'
    outputData.value = jsonToTypeScript(parsed, rootName)
    errorMessage.value = ''
  } catch (error) {
    errorMessage.value = `JSON 解析失?。?{error.message}`
    outputData.value = ''
  }
}

這里做了三件事:輸入清洗、JSON 解析、調(diào)用生成器。只要這一步跑通,工具就能穩(wěn)定輸出。

2)類型名生成:先合法,再去重

JSON 字段名常常不規(guī)范,比如有空格、短橫線、數(shù)字開頭,所以類型名要先標準化:

const toPascalCase = (value, fallback = 'Item') => {
  const cleaned = String(value || '').replace(/[^A-Za-z0-9_$\s]/g, ' ').trim()
  if (!cleaned) return fallback
  const parts = cleaned.split(/\s+/).filter(Boolean)
  const combined = parts.map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('')
  return /^[A-Za-z_$]/.test(combined) ? combined : fallback
}

const normalizeInterfaceName = (value, fallback = 'RootObject') => {
  if (!value) return fallback
  return toPascalCase(value, fallback) || fallback
}

嵌套對象會不斷生成新接口名,所以還要處理重名:

const interfaceNames = new Set()
const processedNames = new Set()

const generateInterfaceName = (base, suffix = '') => {
  const baseNormalized = normalizeInterfaceName(base, 'RootObject')
  const suffixNormalized = suffix ? toPascalCase(suffix) : ''
  const name = `${baseNormalized}${suffixNormalized}`

  if (!interfaceNames.has(name) && !processedNames.has(name)) {
    interfaceNames.add(name)
    return name
  }

  let counter = 2
  while (interfaceNames.has(`${name}${counter}`) || processedNames.has(`${name}${counter}`)) {
    counter += 1
  }
  const finalName = `${name}${counter}`
  interfaceNames.add(finalName)
  return finalName
}

3)類型推斷:遞歸處理對象和數(shù)組

真正的核心在 inferType

const inferType = (value, key, parentName) => {
  if (value === null) return 'null'

  if (Array.isArray(value)) {
    if (value.length === 0) return 'any[]'
    const elementTypes = new Set(value.map(item => inferType(item, 'Item', parentName)))
    const types = Array.from(elementTypes)
    const inner = types.length === 1 ? types[0] : `(${types.join(' | ')})`
    return `${inner}[]`
  }

  if (typeof value === 'object') {
    const nestedName = generateInterfaceName(parentName, key)
    processObject(value, nestedName)
    return nestedName
  }

  if (typeof value === 'string') return 'string'
  if (typeof value === 'number') return 'number'
  if (typeof value === 'boolean') return 'boolean'
  return 'any'
}

比如 [{ id: 1 }, { id: "2" }] 會得到 (RootItem | RootItem2)[] 或聯(lián)合類型形式,保證類型信息不丟。

4)對象轉(zhuǎn)聲明文本

推斷完類型后,要拼成最終代碼:

const formatPropertyKey = key => {
  const value = String(key)
  const identifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/
  return identifier.test(value) ? value : JSON.stringify(value)
}

const processObject = (obj, name) => {
  if (processedNames.has(name)) return
  processedNames.add(name)

  const optionalMark = optionalProps.value ? '?' : ''
  const lines = []
  lines.push(useType.value ? `export type ${name} = {` : `export interface ${name} {`)

  Object.entries(obj).forEach(([key, value]) => {
    const tsType = inferType(value, key, name)
    const propertyKey = formatPropertyKey(key)
    lines.push(`  ${propertyKey}${optionalMark}: ${tsType};`)
  })

  lines.push('}')
  interfaces.push(lines.join('\n'))
}

如果根節(jié)點本身是數(shù)組,再補一行根類型:

if (Array.isArray(json)) {
  const arrayType = inferType(json, 'Item', baseName)
  const rootLine = `export type ${baseName} = ${arrayType};`
  return interfaces.length ? `${interfaces.join('\n\n')}\n\n${rootLine}` : rootLine
}

5)實時轉(zhuǎn)換觸發(fā)

輸入實時更新,但不希望每敲一個字都立即解析,所以用了防抖:

let debounceTimer = null
const scheduleConvert = () => {
  if (debounceTimer) clearTimeout(debounceTimer)
  debounceTimer = setTimeout(() => {
    convert()
  }, 400)
}

watch(jsonInput, scheduleConvert)
watch(interfaceName, scheduleConvert)
watch([useType, optionalProps], convert)

最終效果就是:輸入 JSON、改根接口名、切換 interface/type、切換可選屬性,結果區(qū)都會自動刷新。

6)完整思路總結

這套實現(xiàn)本質(zhì)是三層:

  1. 輸入層:解析 JSON、處理錯誤
  2. 推斷層:遞歸判斷數(shù)據(jù)類型、生成嵌套接口名
  3. 輸出層:拼接 TypeScript 聲明文本

把這三層拆開后,代碼可讀性會很高,讀者也能很容易定位:哪里在“解析”、哪里在“推斷”、哪里在“輸出”。

到此這篇關于JS實現(xiàn)JSON轉(zhuǎn)TypeScript接口的核心步驟的文章就介紹到這了,更多相關JS JSON轉(zhuǎn)TypeScript接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

石河子市| 阿拉善左旗| 锦州市| 南宁市| 大新县| 锡林浩特市| 临清市| 通辽市| 惠东县| 永城市| 石棉县| 雅安市| 宾阳县| 商水县| 绥宁县| 长岛县| 土默特左旗| 温州市| 新平| 贵定县| 陇西县| 香河县| 门头沟区| 汤原县| 买车| 那曲县| 信丰县| 鄯善县| 长寿区| 岢岚县| 平舆县| 弥渡县| 辽中县| 东阿县| 双柏县| 门源| 即墨市| 吐鲁番市| 舒城县| 邵东县| 三穗县|