Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JSONとJSON Schemaを改めて理解する / tokyo_study

JSONとJSON Schemaを改めて理解する / tokyo_study

2023/3/3に発表した資料です。

OKUNOKENTARO

March 03, 2023
Tweet

More Decks by OKUNOKENTARO

Other Decks in Technology

Transcript

  1. +40/ͱ͸ ʢೖ໳ฤʣ w +BWB4DSJQU0CKFDU/PUBUJPO w +BWB4DSJQUͷΦϒδΣΫ τ ɾ Ϧςϥϧͱ਌͍͠දه͕Մೳͳߏ଄Խσʔλఆٛܗࣜ w

    package.json΍tsconfig.jsonͳͲઃఆϑΝΠϧʹ࠾༻͞Ε͍ͯΔͨΊ5ZQF4DSJQU։ൃʹ 
 ͓͍ͯ͸ɺ ΄΅શһ͕໨ʹ͢Δ w +BWB4DSJQUҎ֎ʹ1ZUIPO 1)1 3VCZ (PͳͲ෯޿͍ϓϩάϥϛϯάݴޠͰ+40/ͷม׵͕Մೳ Ͱ͋Δ
  2. +40/ͱ͸ ʢྺ࢙ฤʣ w ೥ɺ ॳظͷ8FCϒϥ΢β/FUTDBQF/BWJHBUPSʹ౥ࡌ͞ΕͨεΫ Ϧ ϓτݴޠ 
 +BWB4DSJQU چ-JWF4DSJQU

     w ओཁ։ൃऀ͸#SFOEBO&JDIࢯ w ͜ͷݴޠʹඋΘ͍ͬͯͨΦϒδΣΫ τ ɾ Ϧςϥϧ͸೥ͷ࣌఺Ͱطʹ/FUTDBQF/BWJHBUPSͷ σʔλަ׵ʹ࠾༻͞Ε͍ͯͨ w ͦͷޙඪ४ԽΛܦͨ&$."4DSJQUͷΦϒδΣΫ τ ɾ ϦςϥϧΛ༻͍ͨσʔλߏ଄දهʹର͠ 
 ೥ʹ%PVHMBT$SPDLGPSEࢯ͕͜ΕΛ+40/ͱ໋໊ w "KBY "TZODISPOPVT+BWB4DSJQU"OE9.- ʹ͓͍ͯ9.-Α Γ ΋ܰྔͰ͋Δ͜ͱ͔Β 
 ೥୅ޙ൒Ҏ߱ɺ +40/͕ීٴ͍ͯ͘͠
  3. ࢓༷͕૬͍࣍Ͱ஀ੜ w ೥݄ʹ*&5'ʹͯ3'$͕ެ։ w ೥݄ʹ&$."UI &4 ͕ެ։ w JSON.parse(), JSON.stringify()͕

    ʢҰ෦ͷྫ֎ΛؚΉ͕ɺ ΄΅ʣ 3'$ʹ४ڌ͠࠾༻ w ೥݄ʹ&$."5IF+40/%BUB*OUFSDIBOHF'PSNBUTU͕ެ։ w ೥݄ʹ&$."UI &4 ͕ެ։ w 3'$͕ґଘ͔Β࡟আɺ طଘͷ+40/ʹؔ͢Δ࣮૷͸&$."ʹ४ڌ΁
  4. ࢓༷ͷ౷Ұ w ೥݄ɺ *&5'ʹͯ3'$͕ެ։ɺ &$."ʹͯ&$."OE͕ެ։ w ޓ͍ͷ࢓༷͸ڞ௨Խ͞Εɺ ࣄ্࣮+40/ʹ͓͚Δ།Ұͷ࢓༷ͱݺͼ͏ Δঢ়ଶ͕੔ͬͨ JSON

    was first presented to the world at the JSON.org website in 2001. A definition of the JSON syntax was subsequently published as IETF RFC 4627 in July 2006. ECMA-262, Fifth Edition (2009) included a normative specification of the JSON grammar. This specification, ECMA-404, replaces those earlier definitions of the JSON syntax. Concurrently, the IETF published RFC 7158/7159 and in 2017 RFC 8259 as updates to RFC 4627. The JSON syntax specified by this specification and by RFC 8259 are intended to be identical. https: / / www.ecma-international.org/wp-content/uploads/ECMA-404_2nd_edition_december_2017.pdf
  5. +40/ͷεΩʔϚ w +40/ͷ࢓༷͸ɺ ͋͘ ·Ͱ΋σʔλߏ଄ఆٛʹඞཁͳߏจΛఆΊ͍ͯΔʹ͗͢ͳ͍ w ͦͷதͷσʔλͻͱͭͻͱͭͷ࢓༷͸ͦͷ+40/࡞੒ऀʹҕͶΒΕΔ w ͨͱ͑͹͜Μͳ৘ใ w

    ͦͷ஋͸ɺ ԿจࣈҎ্Ͱɺ ԿจࣈҎԼͷจࣈྻͰ͋Δ w ͦͷ஋͸ɺ ྻڍ͞ΕͨϓϩύςΟ ΛඞؚͣΉΦϒδΣΫ τͰ͋Δ w ͦͷ஋͸ɺ ಛఆͷ୯ޠͷΈͰߏ੒͞ΕΔ഑ྻͰ͋Δ w +40/ʹର͢Δ͜ͷΑ ͏ͳεΩʔϚ৘ใΛѻ͍͍ͨͱ͍͏ཉٻ͕ੜ·Ε࢝ΊΔ
  6. +40/4DIFNB w +40/ͰѻΘΕΔϓϩύςΟ΍஋ͷߏ଄ ɾ ܕΛఆٛ͢ΔͨΊͷܗࣜΛ+40/4DIFNBͱ͍͏ w ೚ҙͷ+40/ͷσʔλ࢓༷Λ ʮ+40/4DIFNBͱ͍͏+40/ʯ Ͱදݱ͢Δ w

    +40/4DIFNB͸ͭͷ࢓༷ʹΑ Γ੒Γཱ͍ͬͯΔ w +40/4DIFNB$PSF+40/4DIFNBͷجૅͱͳΔఆٛ w +40/4DIFNB7BMJEBUJPO֦ு࢓༷ͱͯ͠όϦσʔγϣϯʹؔ͢Δࣄ߲ͷఆٛ
  7. +40/4DIFNBͷ8FCඪ४Խ͸ ʁ w +40/4DIFNBͷ൛͸ESBGU΍ESBGUͷΑ ͏ʹESBGU઀಄͕ࣙ෇͘ w ͜Ε͸*&5'ʹର͢ΔESBGUͱ͍͏ҙຯͰ͋Γ 
 BKWͳͲͷ+40/4DIFNBΛղऍ͢ΔόϦσʔγϣϯ ɾ

    ϥΠ ϒϥ Ϧ͸ɺ ࣄ্࣮͜ΕΛਖ਼نͷ࢓༷ͱͯ͠ ѻ͍ͬͯΔ w ΋͸΍ESBGU͔ͩΒͱͯ͠ෆ҆ఆͱ͍͏ҙຯͰ͸ͳ͘ɺ ܗࣜతʹESBGU઀಄͕͍͍ࣙͭͯΔঢ়گ w KTPOTDIFNBPSH͸༗ࢤͷஂମͰ͋Γ*&5'ͷϫʔΩϯάάϧʔϓͰ͸ͳ͍ w Αͬͯ*&5'ඪ४Խϓϩηε͔Βͷ୤٫Λਤ͍ͬͯΔ໛༷ https: / / github.com/json-schema-org/json-schema-spec/blob/main/adr/2022-09-decouple-from-ietf.md
  8. 8FCඪ४Խ͍ͯ͠ͳ͍΋ͷΛ҆৺ͯ͠࢖͑Δ͔ ʁ w +40/4DIFNBʹ͍ͭͯͷٞ࿦ͱվగͷܾఆ͸͢΂ͯΦʔϓϯʹͳ͍ͬͯΔ w ͢Ͱʹ೥͔Βͷ࢓༷ͷ஝ੵͱීٴʹΑ Γɺ ੈքதͷ։ൃऀ͔Βؔ৺͕دͤΒΕ͍ͯΔ w *&5'ඪ४Խϓϩηεʹ؇΍͔ʹଇΓESBGUΛॏͶ͖ͯͨ͜ͱ͔Βɺ

    
 ࢓༷ॻࣗମͷ඼࣭΋͓͟ͳΓͰ͸ͳ͍ w 8FCඪ४Խ͞Εͣʹ8FC։ൃपลʹͯීٴٕͨ͠ज़͸ଞʹ΋͍ͭ͘΋͋Δ w ӦརஂମʹΑͬͯ࡞੒͞ΕσϑΝΫ τελϯμʔ υͱͯ͠ීٴͨ͠0(1΍ɺ 
 ઐ༻ͷඇӦརஂମʹΑͬͯ؅ཧ͞ΕΔ.BSLEPXO :".-ͳͲ
  9. KTPOTDIFNBUPUT w ;PE͕ྲྀߦ͍ͯ͠Δ w ;PE͸5ZQF4DSJQU༻ϥΠ ϒϥ ϦͰ͋Γɺ ܕఆٛੜ੒͓Αͼ3VOUJNF7BMJEBUPSͷఏڙΛߦ͏ w ࣮͸+40/4DIFNBΛ࢖ͬͯ΋͍ۙ͜ͱ͕Ͱ͖Δ

    w KTPOTDIFNBUPUTͱ͍͏ ϥΠ ϒϥ ϦΛ࢖͏ 
 https: // github.com/ThomasAribart/json-schema-to-ts#readme w FromSchema<typeof schema>ͷΑ ͏ʹͯ͠+40/4DIFNBΛදݱͨ͠ΦϒδΣΫ τ ɾ Ϧςϥϧ Λ֨ೲ͢Δม਺ͷܕΛtypeof෇͖Ͱ౉͢ͱɺ +40/4DIFNBʹج͍ͮͨܕΛੜ੒͢Δ w όϦσʔγϣϯॲཧʹ͸BKWΛ࢖͏
  10. ࢖͍ํ const schema1 = { $schema: 'http://json-schema.org/draft-07/schema#', type: 'string', }

    as const satisfies JSONSchema7; const schema2 = { $schema: 'http://json-schema.org/draft-07/schema#', type: 'null', } as const satisfies JSONSchema7; type T1 = FromSchema<typeof schema1>; type T2 = FromSchema<typeof schema2>; assertType<T1, string>(true); assertType<T2, null>(true); w as const satisfies JSONSchema7 
 Λ࢖͏ ͱิ׬͕ޮ͍ͯศར w type: 'string'ͷ4DIFNB͔Β͸ stringܕ͕ಘΒΕΔ
  11. const schema = { $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', properties: {

    foo: { type: 'number' }, bar: { type: 'boolean' }, }, } as const satisfies JSONSchema7; type T = FromSchema<typeof schema>; assertType< T, { [x: string]: unknown; foo?: number; bar?: boolean; } >(true); const schema = { $schema: 'http://json-schema.org/draft-07/schema#', type: 'object', additionalProperties: false, properties: { foo: { type: 'number' }, bar: { type: 'boolean' }, }, required: ['foo'], } as const satisfies JSONSchema7; type T = FromSchema<typeof schema>; assertType< T, { foo: number; bar?: boolean; } >(true); w required΍additionalProperties͕ࢦఆ͞Ε͍ͯͳ͍ w [x: string]: unknown;΍0QUJPOBMؚ͕·ΕΔ w additionalProperties: falseͩͱ[x: string]: unknownࢦఆ͸ؚ·Εͳ͍ w requiredʹج͍ͮͯ0QUJPOBM͕֎ΕΔ
  12. w ഑ྻ΋ѻ͏ ͜ͱ͕Ͱ͖Δ w 6OJPOܕͷදݱʹ͸oneOfΛ༻͍Δ const schema = { $schema:

    'http://json-schema.org/draft-07/schema#', type: 'array', items: { oneOf: [ { type: 'string' }, { type: 'object', properties: { foo: { type: 'number' } } }, ], }, } as const satisfies JSONSchema7; type T = FromSchema<typeof schema>; assertType< T, ( | string | { [x: string]: unknown; foo?: number; } )[] >(true);
  13. ੯͍͠ͱ ͜Ζ w $refʹ͸ରԠ͍ͯ͠ΔͷͰ֎෦εΩʔϚ΋ಡΊΔ w ϑΝΠϧΛ௒͑ͨ͋ͨΓͰ5ZQF4DSJQUίϯύΠ ϥͷ࠶ؼͷݶքʹḷΓண͍ͨͷͰ 
 $refલఏͷεΩʔϚࡉ෼ԽΞʔΩςΫνϟͩͱ٧Ή w

    ഑ྻͷόϦσʔγϣϯ༻ଐੑminItems, maxItemsͳͲΛઃఆͯ͠΋ 
 string[]͕[string, string, string]ʹͳͬͨΓ͸͠ͳ͍ w ࡉ͔͍ͱ͜Ζ͸ࠓޙʹظ଴͍ͨ͠