TypeScriptの概要とLanguage Server Protocol / About TypeScript & Language Server Protocol

TypeScriptの概要とLanguage Server Protocol / About TypeScript & Language Server Protocol

https://www.microsoft.com/ja-jp/events/decode/2017/sessions.aspx
Microsoftのde:code 2017で登壇して喋ったやつです。

0e797080b64e6b03ed00964cf69b5058?s=128

Masahiro Wakame

May 24, 2017
Tweet

Transcript

  1. 7.
  2. 11.
  3. 14.

    ECMAScript ͱ͸ • ECMAScript͸JavaScriptͷඪ४ن֨ • 3, 5, 2015, 2016, 2017...

    ͳͲ͕ଘࡏ͢Δ • 6 → 2015 ʹͳΓ·ͨ͠ • 2015Ͱclass, module ͳͲ৽ن࠾༻ ཁ͢Δʹ == JavaScript goo.gl/lZyVX8
  4. 16.

    ͪΐͬͱུޠͷղઆ • ES → ECMAScript • JS → JavaScript •

    TS → TypeScript • AltJS → Alternative JS AltJS͸ΘΓͱద౰ ୅ସ
  5. 17.

    AltJS͸ඞཁͩͬͨ • લఏɿES 5͸ਏ͍… • Կ͔ to JS Ͱܰݮ͍ͨ͠…ʂ •

    CoffeeScript • Dart • TypeScript • Babel & Flowtype Babel͸ਖ਼௚ ධՁͰ͖Δ΄Ͳ ࢖ͬͯ·ͤΜ(খ੠
  6. 18.

    Ұ൪༏͍͠AltJS • CoffeeScriptɺES5ΑΓϚγ • Ͱ΋ΊͬͪΌόάΔʢܕແ͍ • ܕʹཔͬͯੜ͖ͯΔϚϯʹ͸ਏ͍… • DartʹυϋϚϦ •

    Ͱ΋ϩοΫΠϯ͸ා͍… • ίϯύΠϧޙJS͸ਓؒʹ͸ಡΊͳ͍ • ܧଓੑʹ֬৴͕࣋ͯͳ͍ ձࣾͰ࠾༻͸ා͔ͬͨ…
  7. 20.

    TypeScript͕ੜ੒͢ΔJSίʔυ • HTML + ES Modules ྫ • Classes ྫ

    • Types ྫ • Downpile ྫ ϩοΫΠϯ͞Εͳ͍ ཧ༝Λݟͤ·͢ʂ
  8. 21.

    HTML+ES Modules <html> <body> <script type="module" src="./lib/index.js"></script> </body> </html> import

    { hello } from "./sub.js"; alert(hello("es module")); export function hello(word = "world") { return `Hello, ${word}`; }
  9. 22.

    ม׵ޙ <html> <body> <script type="module" src="./lib/index.js"></script> </body> </html> import {

    hello } from "./sub.js"; alert(hello("es module")); export function hello(word = "world") { return `Hello, ${word}`; } ΄΅Ұக
  10. 23.

    Classes TSฤ export abstract class Animal { abstract bark(): string;

    } export class Cat extends Animal { bark(): string { return "ʹΌʔΜ"; } } const cat = new Cat(); console.log(cat.bark());
  11. 24.

    Classes JS(esnext)ฤ export class Animal { } export class Cat

    extends Animal { bark() { return "ʹΌʔΜ"; } } const cat = new Cat(); console.log(cat.bark());
  12. 25.

    Classes JS(es5)ฤ "use strict"; var __extends = (this && this.__extends)

    || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var Animal = (function () { function Animal() { } return Animal; }()); exports.Animal = Animal; var Cat = (function (_super) { __extends(Cat, _super); function Cat() { return _super !== null && _super.apply(this, arguments) || this; } Cat.prototype.bark = function () { return "ʹΌʔΜ"; }; return Cat; }(Animal)); exports.Cat = Cat; var cat = new Cat(); console.log(cat.bark());
  13. 26.

    Types TSฤ export interface Container<T> { data: T; } export

    function unwrap<T>(container: Container<T>): T { return container.data; } type RetStringFunc = () => string; const container: Container<RetStringFunc> = { data: () => "Hello, world", }; const func = unwrap(container); console.log(func());
  14. 27.

    Types JS(esnext)ฤ export function unwrap(container) { return container.data; } const

    container = { data: () => "Hello, world", }; const func = unwrap(container); console.log(func());
  15. 28.

    Downpile TSฤ function* primes() { const primes: number[] = [];

    for (let i = 2; ; i++) { if (primes.some(prime => i % prime === 0)) { continue; } primes.push(i); yield i; } } for (const prime of primes()) { if (100 < prime) { break; } console.log(prime); } ΄΅׬શʹ ੜJSʂ : number[] ͷΈ
  16. 29.

    Downpile JS(es5)ฤ "use strict"; var __generator = (this && this.__generator)

    || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function (o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; }; function primes() { var primes, _loop_1, i; return __generator(this, function (_a) { switch (_a.label) { case 0: primes = []; _loop_1 = function (i) { return __generator(this, function (_a) { switch (_a.label) { case 0: if (primes.some(function (prime) { return i % prime === 0; })) { return [2 /*return*/, "continue"]; } primes.push(i); return [4 /*yield*/, i]; case 1: _a.sent(); return [2 /*return*/]; } }); }; i = 2; _a.label = 1; case 1: return [5 /*yield**/, _loop_1(i)]; case 2: _a.sent(); _a.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); } try { for (var _a = __values(primes()), _b = _a.next(); !_b.done; _b = _a.next()) { var prime = _b.value; if (100 < prime) { break; } console.log(prime); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_b && !_b.done && (_c = _a.return)) _c.call(_a); } finally { if (e_1) throw e_1.error; } } var e_1, _c; ৽͠Ίͷ ίʔυͰ ࢮͳͳ͍ʂ
  17. 31.

    JSͱͷߏจൺֱ • ม਺ʹର͢Δܕ஫ऍ • ؔ਺ʹର͢Δܕ஫ऍ • ߏ଄త෦෼ܕ • type assertion

    • ͦͷଞࡉ͔͍දݱ͕ͨ͘͞Μ • →JS͕ࣗ༝͗͢ΔͷͰ ੲ͸ؤுΕ͹ ͋Β͔ͨ঺հͰ͖ͨ ࠓ͸΋͏ແཧ…
  18. 32.

    ม਺ʹର͢Δܕ஫ऍ // ม਺໊ͷޙʹ : ܕ໊ let str: string = "";

    // ܕʹ൓͢Δ஋ΛೖΕΑ͏ͱ͢ΔͱίϯύΠϧΤϥʔ str = 1; // ઃఆ࣍ୈͰ null ΍ undefined ΋νΣοΫՄೳ str = null; str = undefined; let num = 1; // ஋͔Βܕ͕ਪ࿦͞ΕΔͷͰnumberҎ֎͸μϝ num = "string"; // ഑ྻͱ͔ unionܕͱ͔ let array: (number | string)[] = [1, "str"];
  19. 33.

    ؔ਺ʹର͢Δܕ஫ऍ // ԾҾ਺ͷޙʹ : ܕ໊ & ฦΓ஋ͷܕ໊ let twice: (num:

    number) => number; twice = num => num * 2; console.log(twice(2)); // লུՄೳҾ਺ let helloA = (word?: string) => { word = word || "world"; return `Hello, ${word}`; }; console.log(helloA()); // σϑΥϧτ஋෇͖Ҿ਺ (ES2015) let helloB = (word: string = "world") => { return `Hello, ${word}`; }; console.log(helloB());
  20. 34.

    ؔ਺ʹର͢Δܕ஫ऍ // ԾҾ਺ͷޙʹ : ܕ໊ & ฦΓ஋ͷܕ໊ let twice: (num:

    number) => number; twice = num => num * 2; console.log(twice(2)); // লུՄೳҾ਺ let helloA = (word?: string) => { word = word || "world"; return `Hello, ${word}`; }; console.log(helloA()); // σϑΥϧτ஋෇͖Ҿ਺ (ES2015) let helloB = (word: string = "world") => { return `Hello, ${word}`; }; console.log(helloB());
  21. 35.

    ߏ଄త෦෼ܕ class SampleA { name: string; constructor(name: string) { this.name

    = name; } } interface SampleB { name: string; } let objA: SampleA = new SampleA("A"); let objB: SampleB = { name: "B" }; // ίϯύΠϧΤϥʔʹͳΒͳ͍ʂ // SampleA ͱ SampleB ͸ಉ͡ੑ࣭Λຬͨ͢ͷͰޓ׵ੑ͕͋Δ objA = objB;
  22. 36.

    type assertion // type assersionΛߦ͏ͱܕΛม׵Ͱ͖Δ // ԿͰ΋OKΛද͢ any ΛڬΊ͹޷͖ͳ͜ͱ͕Ͱ͖Δ //

    ؾܰʹ࢖ͬͯ͸͍͚ͳ͍…ʂ let objA: string = new Date() as any as string; // ͜͏͍͏ॻ͖ํ΋Ͱ͖Δ let objB: string = <string><any>new Date();
  23. 37.

    Version Up ͷาΈ • 2012/10/01 v0.8.0 • 2014/04/02 v1.0.0 •

    2016/09/22 v2.0.3 • ΄΅׬੒ܥͰ͸ʁ • 2017/04/28 v2.3.2 ೔෇͸GMTͰ͢
  24. 40.

    طଘࢿ࢈ͷ׆༻ • JSϥΠϒϥϦΛ࢖͍͍ͨʂ • ܕఆٛϑΝΠϧΛޙ෇͚ • ·ΔͰܕ͕͋ΔΈ͍ͨʂ • ܕఆٛϑΝΠϧ •

    ࣗ෼Ͱॻ͘ • DefinitelyTypedͰ୳͢ • microsoft.github.io/TypeSearch/ • npm install -D @types/node npmܦ༝ʹ ౷Ұʂ
  25. 41.

    vs Babel • ݁ہͲͬͪΛ࠾༻͢΂͖ʂʁ • →νʔϜ࣍ୈ • ๻͸RubyΑΓ͸Java೿ • →RubyΛબ୒͠੒ޭ͢ΔνʔϜ΋͋Δ

    • TSΛ͓͢͢Ί͢Δਓ • IDE΍ϦονͳΤσΟλ΄͍͠ʂ • Java΍C#͕޷͖ʂ • ҆શͳϦϑΝΫλϦϯάʂ ΄΅ फڭઓ૪ σϞΔʁ
  26. 42.

    vs ੜJavaScript • ݱ࣌఺Ͱ͸೉͍͠ • ࣌୅͕௥͍͍ͭͯͳ͍ • bundler͕·ͩඞཁ • IE11͍ͭ੾Δͷ໰୊

    • ϥΠϑλΠϜ͕·ͩ·ͩ͋Δ • Ҋ݅ͷҒ͍ਓIE11໰୊ ୤πʔϧ ೉͍͠… ΍ΊΖʔʂ
  27. 43.

    TypeScript ಋೖฤ • npm init —yes • npm install -D

    typescript • tsc —init • npm-scripts • "build": “tsc" • VSCodeͷઃఆͳͲ Node.jsࣗମ͸ nodebrew͕͓͢͢Ίʂ Windowsͷ৔߹…ʁ
  28. 44.

    TypeScript ܕFight • ܕఆٛϑΝΠϧࣗ࡞͸Ͱ͖Δͱخ͍͠… • Document & Handbook • www.typescriptlang.org/docs/home.html

    • Revised TypeScript in Definitelyland • qiita.com/vvakame • όʔδϣϯࠩ෼·ͱΊ ॻ͍ͯ·͢ ࣾ಺ʹ1ਓ ܕϑΝΠλʔ͕͍Δͱྑ͍ ಘ೉͍
  29. 49.

    LSPͷ࢓༷ • Microsoft͕΍ͬͯΔ • github.com/Microsoft/language-server-protocol • ΤσΟλˠClient • ݴޠଆˠServer •

    JSON-RPCͰϓϩηεؒ௨৴ • ΤσΟλͰ໾ཱͭ৘ใΛ΍ΓͱΓ ࣮૷ݴޠґଘΛ͔ΘͤΔ
  30. 51.

    ͜ΕɺTypeScriptʹ͋Γ·͢ • tsserverίϚϯυ • Language ServiceΛϥοϓ • ଟ͘ͷΤσΟλͰߴΫΦϦςΟͷ
 TypeScriptαϙʔτ •

    VSCode, Atom, WebStorm, Vim etc.. • ཪʹ͸tsserver͕ʂ • tsserver͸࣮͸LSP४ڌͰ͸ͳ͍… • ઌۦऀ͔ͩΒͶ ࢓ํͳ͍Ͷ goo.gl/HD4noG
  31. 55.

    • JSX https://jsx.github.io/ • ͱ͍͏DeNA࢈ͷAltJS͕͋ͬͨ • Eclipse༻ϓϥάΠϯ͕ཉ͔ͬͨ͠ • https://github.com/vvakame/jsx-plugin-for-eclipse •

    ͍͢͝ਏ͍ • ݴޠ֦ுϓϥάΠϯͷ
 ࡞ΓํͷखҾ͕΄΅ͳ͍ JSX + EclipseϓϥάΠϯͷࢥ͍ग़ μϯδϣϯ͔ Կ͔ʹ͍ۙ
  32. 56.

    εΩϧϛεϚον໰୊ • ݴޠ։ൃऀ • ػೳ։ൃ͍ͨ͠ • IDEɾΤσΟλ։ൃऀ • શݴޠରԠͱ͔ඇݱ࣮త •

    ϓϥάΠϯͰͳΜͱ͔ͯ͠Ͷ • ී௨ʹίʔυॻ͖͍ͨਓ • ↑࣌ʹ͸ϓϥάΠϯॻ͔͟ΔΛ͑ͳ͍ • ׳Εͯͳ͍ͷͰଟେͳۤ௧Λ൐͏ ୭͕టΛ ඃΔͷ͔
  33. 58.

    LSP΍ͬͯΈͨ • ࣗ෼Ͱ࡞ͬͯΈͨ • prhͱ͍͏ٕज़ॻͳͲߍਖ਼༻πʔϧ • ͜ΕΛLSPରԠͤͯ͞ΈΑ͏ʂ • ࣮૷Ͱ͖ͨػೳ •

    ྑ͘ͳ͍දݱͷݕग़ • Quick Fix • จॻதͷશީิΛҰׅFix • ઃఆͷࣗಈ࠶ಡࠐ github.com/prh/ vscode-prh-extention
  34. 59.

    LSP΍ͬͯΈͨ • ن໛ • languageserver ໿300ߦ • vscode֦ு ໿100ߦ •

    ࣦͬͨ΋ͷ ΰʔϧσϯ΢ΟʔΫ • σϞ • VSCode্Ͱಈ༷͘ࢠ Θ͔Ε͹؆୯ʂ
  35. 62.

    ؔ࿈npmύοέʔδ • Server • vscode-languageserver • vscode-uri • Client (VSCode

    ext) • vscode-languageclient • ֤Language Server΁ͷύε
  36. 65.

    ͦͷଞ • Rust Language Server • github.com/rust-lang-nursery/rls • Jonathand Turnerࢯͱ͔͕࡞ͬͯΔ

    • Rustࣗମ͸ػೳΛϗετͤͣ • ਫ਼౓͸ظ଴ͨ͠΄ͲͰ͸ͳ͍ • list.get(0). Ͱิ׬͕Ͱͳ͘ͳͬͨΓ Rust+WASMॻ͍ͨ goo.gl/kjMffu
  37. 68.

    Language Service Plugin • ͱΓ͋͑ͣLSPͱུ… ةݥ͕ةͳ͍ʂ • ΊΜͲ͍ͷͰϓϥάΠϯͱݺ΅͏ • ͜Ε͸TypeScriptݻ༗ͷػೳ

    • Language Serviceͷॲཧʹ1ຕטΊΔ • ͭ·Γtsserverʹ΋1ຕטΊΔ • tscʹ͸טΊͳ͍ ηογϣϯλΠτϧ ࠷ॳؒҧ͑ͯ·ͨ͠…
  38. 74.

    ͓͞Β͍ • TypeScript͸ • ϩοΫΠϯ͞ΕͮΒ͍ • IDE΍ΤσΟλ͕ߴػೳ • ࠾༻ࣄྫ΋૿͑ͨ •

    Language Server Protocol • ָ͍͠ʂ • ଞݴޠʹ΋ঃʑʹ޿͕Δ͔΋ ͜ͷޙAsk the speakerͰ ૬ஊͱ͔Ͱ͖·͢ʂ