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

TypeScript LSP の今までとこれから

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

TypeScript LSP の今までとこれから

Avatar for Yosuke Kurami

Yosuke Kurami

June 06, 2025
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. TypeScript ͷΤσΟλαϙʔτ - Strada(TypeScript < 7) ʹ͸ tsserver ͱ͍͏ϓϩάϥϜ͕ಉࠝ͞Ε͍ͯΔ -

    ΤσΟλ (e.g. VSC, Vim, etc, ) ͸ tsserver ͱ௨৴͢Δ͜ͱͰϢʔβʔʹίʔ σΟϯάͷศརػೳΛఏڙ͍ͯ͠Δ - ίʔυิ׬, ΤϥʔνΣοΫ, Quick fi x, Organize Import, etc,,,
  2. Language Server Protocol - LSP (Language Server Protocol) : -

    MicroSoft ͕ࡦఆͨ͠ ΤσΟλ - ݴޠαʔϏεؒͷ౷ҰతͳΠϯλʔϑΣΠε - LSP ʹΑΓɺΤσΟλଆ͸ Plugin ͷ࣮૷ίετ͕֨ஈʹԼ͕Δ -41ͷͳ͍ੈք -41ͷ͋Δੈք
  3. Language Server Protocol ? - tsserver ͸ LSP Λ࣮૷͍ͯ͠ͳ͍ tsserver

    should implement the Language Server Protocol #11274 - tsserver ͸ LSP ͸࣮૷͍ͯ͠ͳ͍ (େࣄͳ͜ͱͳͷͰry tsserver should implement the Language Server Protocol #39459 - TypeScript Λ LSP Ͱѻ͏ͨΊʹ͸ɺ3rd party ੡ͷΞμϓλΛט·ͤΔ౳ ͷख͕ؒඞཁͳঢ়گ͕ଓ͍͍ͯΔ 😇
  4. LSP ͷྺ࢙ - 2015.4 ݄ʹ TypeScript 1.5-alpha Ͱ tsserver ͕ެ։͞Εͨ

    (߹Θͤͯ MS ͸ Sublime Text ޲͚ͷϓϥάΠϯ΋ϦϦʔε͍ͯ͠Δ) - ಉ࣌ظʹ C# (.NET) ͷίϛϡχςΟͰ OmniSharp ͱ͍͏ݴޠαϙʔτ͕։ൃ͞Εͨ - 2015.4 ݄ͷ Build Ͱ VSC ൃදɻ VSC Ͱ OmniSharp, tsserver ͷ૒ํʹରԠͤ͞Δ Plugin Λ։ൃ͢ΔաఔͰ LSP ͷߏ૝ ͕࢝·Δ ( https://github.com/microsoft/language-server-protocol/wiki/Protocol-History ) - 2016೥ʹ Microsoft ͕ LSP Λެ։ LSP ͷ JSON RPC ௨৴࢓༷͸ tsserver, OmniSharp ͷӨڹΛڧ͘ड͚͍ͯΔɻ ಛʹ tsserver ͸ stdio Λτϥϯεϙʔτʹ࠾༻͍ͯ͠ΔͨΊɺࠓ೔ͷ LSP ͷૅͱݴͬͯ ΋աݴͰ͸ͳ͍
  5. tsserver v.s. LSP - TypeScript ͷ LSP αϙʔτ͕ਐ·ͳ͔ͬͨཧ༝͸ҎԼ͕ߟ͑ΒΕΔ: - LSP

    ͕ tsserver / VSC ͕αϙʔτ͍ͯ͠ΔػೳΑΓ΋ශऑͩͬͨ ྫ: Diagnostic pull model ( LSP 3.17 Ͱඪ४Խ͞Εͨ) https://github.com/microsoft/TypeScript/issues/39459#issuecomment-774538570 - TypeScript ͷϝϯςφ͸ LSP ൛ͱ tsserver ͱ͍͏2ͭͷ࣮૷Λμϒϧ ϝϯς͢Δखؒ͸ආ͚͍ͨ https://github.com/microsoft/TypeScript/issues/39459#issuecomment-696179304
  6. Corsa ͱ tsserver - Corsa Ͱ͸ LSP ϕʔεͷݴޠαʔόʔΛఏڙ༧ఆ https://devblogs.microsoft.com/typescript/announcing-typescript-native-previews/#editor- support-&-lsp-progress

    - Preview ൛Ͱ΋ (ݶఆతͰ͸͋Δ͕) ར༻Մೳɻ tsc -> tsgo ͱҧ͍ɺ୯७ ͳ porting Ͱࡁ·ͣɺҠ২࡞ۀʹ͕͔͔࣌ؒΔɻStrada ͕࣋ͭେྔͷ Integration Test (௨শ Fourslash ) ΛͲ͏΍ͬͯҠߦͤ͞ΔͷʁͳͲͷ՝ ୊͸͋Δ͕ɺண࣮ʹਐΈͦ͏ https://github.com/microsoft/TypeScript/issues/61742
  7. ΋͏ͻͱͭͷ "LSP" - TypeScript ʹ͸ Language Service Plugin ͱ͍͏ػߏ͕ଘࡏ͢Δ ϢʔβʔϥϯυଆͰ

    TypeScript ͷ Language Service ͕࣋ͭϝιουͷ ॻ͖׵͕͑Մೳ - ৄ͘͠͸ @mizdra ͞Μͷ TSKaigi 2025 ൃදࢿྉΛಡΉͱΑ͍ TypeScript Language Service Plugin Ͱ CSS Module ͷ։ൃମݧΛվળ͢Δ - ࣗ෼΋ز͔ͭͷ LS Plugin Λ OSS ͱͯ͠ఏڙ͍ͯ͠ΔͨΊɺ Corsa Ͱ LS Plugin ͕Ͳ͏ͳΔ͔͸ଞਓࣄͰ͸ͳ͍ e.g. ts-graphql-plugin, eslint-typescript-language-service,
  8. LS Plugin ͷجຊ - LS Plugin ͸ tscon fi g.json

    ͷ plugins ʹهࡌ͢Δ͜ͱͰ༗ޮԽ͞ΕΔ (ҎԼ͸ ts-graphql-plugin ͷREADME ΑΓൈਮ) -
  9. Corsa ͱ LS Plugin - typescript-go ͷ discussion ʹΑΔͱ: https://github.com/microsoft/typescript-go/discussions/455#discussioncomment-12467973

    - ۩ମత͸ະఆ͕ͩɺLS ͷ Plugin ػߏͷߏ૝͸͋Δͱͷ͜ͱ - LSP ͷ JSON RPC Payload Λ Intercept ͢ΔܗͰߟ͑Ε͹͍͍ͷͰ͸ɺͱͷ͜ͱ - ԼਤͷΑ͏ͳײͩ͡Ζ͏͔ʁ (஫: ͜Ε͸ Quramy ͷໝ૝Λਤʹ͚ͨͩ͠)
  10. ίʔυϨϕϧͰߟ͑Δ - Strada (TypeScript < 7) ʹ͓͚Δ LS Plugin ͷίʔυ͸ҎԼͷΑ͏ͳܗ

    export = () => { return { create(info: ts.server.PluginCreateInfo) { const originalLs = info.languageService; return { ...originalLs, getQuickInfoAtPosition(fileName: string, pos: number) { // ݩͷ Language Service ϝιουΛ࣮ߦ const originalResult = originalLs.getQuickInfoAtPosition( fileName, pos ); // ϑΝΠϧͷ AST Λऔಘ const sourceFile = info.project.getSourceFile(fileName as ts.Path); // AST ղੳ const result = analyzeAST(sourceFile, pos); return mergeResult(originalResult, result); }, } satisfies ts.LanguageService; }, }; };
  11. ίʔυϨϕϧͰߟ͑Δ - Corsa ͷੈքͰ͸...? export = () => { return

    { create(info: ts.server.PluginCreateInfo) { const originalLs = info.languageService; return { ...originalLs, getQuickInfoAtPosition(fileName: string, pos: number) { // ݩͷ Language Service ϝιουΛ࣮ߦ const originalResult = originalLs.getQuickInfoAtPosition( fileName, pos ); // ϑΝΠϧͷ AST Λऔಘ const sourceFile = info.project.getSourceFile(fileName as ts.Path); // AST ղੳ const result = analyzeAST(sourceFile, pos); return mergeResult(originalResult, result); }, } satisfies ts.LanguageService; }, }; }; ϥοϓݩͷݴޠαʔϏεػೳͷݺͼग़͠ ຊ࣭తʹ-41ͷϨεϙϯεͱ౳Ձɻ ΠϯλʔηϓλͰஔ׵Ͱ͖ͦ͏ +4ଆͰ"45ղੳͰ͖Δ࢓૊Έ͕ඞཁ ͢ͳΘͪɺ$PSTBʹ͓͚Δ$PNQJMFS"1*Ͱ ಉ౳ͷ͜ͱ͕Ͱ͖Δͷ͔͕ϙΠϯτ 1MVHJOͷΤϯτϦํࣜ͸Θ͔Βͳ͍͕ɺ Ұ୴Ͳ͔͜Β͔/PEFKTͷϓϩηε͕ىಈ ͞ΕΔͱ૝ఆ
  12. (ิ଍) Corsa ͱ Compiler API - Compiler API ʹ͍ͭͯ͸ɺtypescript-go ʹ࠷খݶͷج൫෦෼͸

    commit ͞Ε͍ͯΔ https://github.com/microsoft/typescript-go/pull/711 - ઌ΄Ͳͷ project.getSourceFile() Ͱ AST Λऔಘ͢ΔՕॴ΋࣮૷͞Ε͍ͯΔͨΊɺ Corsa Ҡߦޙ΋ JS ͔Βࠓͱಉ༷ͷײ֮Ͱ AST ղੳΛ࣮૷Ͱ͖ͦ͏ - getSourceFile ͷ࣮ଶ͸ IPC Ͱ͋Δ͕ɺlibsyncrpc ͕ར༻͞Ε͓ͯΓ JS ଆ͔Β͸ैདྷͷ Compiler API ͱಉ͘͡ಉظతͳݺͼग़͕͠Մೳ
  13. ݸਓతͳؾʹͳΓ - LSP Λ௨Δ JSON RPC Request ͷස౓Ͱ Plugin-Native ؒͰ

    AST సૹ͕ൃੜ͠ ͯ໰୊ͳ͍ͷ͔ʁ - ྫ: Completion ܥͷίϚϯυ͸ίʔυ͕Ϣʔβʔ͕λΠϐϯά͢ΔͨͼʹϦ ΫΤετ͞ΕಘΔ - Plugin ͕ Interceptor ͔Β sourceFile Λཁٻ͢ΔͱɺLSP ͷ RPC ϦΫΤε τຖͰ AST సૹ͕ൃੜ͢Δ (୯७ͳ JSON Ͱ͸ͳ͘ Flatten ͳ Uint8Array) Strada Ͱ͸ plugin ίʔυ͕ ಉҰϓϩηεͷ sourceFile ʹ௚઀ΞΫηεͰ͖ ΔͨΊɺߴස౓ͷ document มߋԼͰ΋ TypeScript ͕͍࣋ͬͯΔ Incremental Parse ͷԸܙΛڗडͰ͖͕ͨɺݱঢ় Corsa ͷ IPC ϕʔεͷ API Ͱ͸ͦΕ͸ແཧͦ͏
  14. recap - TypeScript ͱ Language Server Protocol - Corsa ͰΑ͏΍͘

    TypeScript ͸ LSP Λਖ਼ࣜʹ໊৐ΕΔΑ͏ʹͳΔΑ - TypeScript Language Service Plugin - Plugin ػߏͷߏ૝ࣗମ͸͋Δ΋ͷͷɺPlugin ͷϩʔυํࣜ΍ AST స ૹΦʔόʔϔουͳͲɺෆ໌ྎͳ෦෼͸ґવͱͯ͠ଟ͍ - ൺֱత੔උ͕ਐΜͰ͍Δ Compiler API पΓ͔Β௥͏ͱΑͦ͞͏