Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
業務に残された「良くない型」で考える「TypeScriptの難しさ」
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Saji
May 21, 2026
Technology
5.9k
4
Share
業務に残された「良くない型」で考える「TypeScriptの難しさ」
TSKaigi2026
-
https://2026.tskaigi.org/talks/5
X
-
https://twitter.com/sajikix
Saji
May 21, 2026
More Decks by Saji
See All by Saji
It’s “Time” to use Temporal
sajikix
3
320
ユーザーが作成したコードをブラウザ上で安全に実行できる Plugin システムへのアプローチ
sajikix
1
710
Branded Typesで日時の複雑さと戦う
sajikix
4
1.2k
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
1
680
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
350
Lookback TypeScript ESM support and what should we do now.
sajikix
5
810
フロントエンドで日時処理と戦うために 2025 ver
sajikix
6
4.7k
先取り!Temporal
sajikix
0
310
アプリ文言のパースで学ぶ 文字列Literal型パズル入門
sajikix
3
1.3k
Other Decks in Technology
See All in Technology
個人最適 から 全体最適 へ AI情報共有会・AIギルド・AI-DLC で進める カンリーの組織展開
rfdnxbro
0
1.4k
[モダンアプリ勉強会]今更聞けないGit/GitHub入門
tsukuboshi
0
240
はじめてのDatadog
kairim0
0
270
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
130
Gradle×GitHub_ActionsでCI時間を約50%短縮 ジョブ分割の設計と落とし穴 / Cutting CI Time by ~50% with Gradle and GitHub Actions: Job-Splitting Design and Pitfalls
takatty
0
620
【Gen-AX】20260530開催_JJUG CCC 2026 Spring
genax
0
410
PHP と TypeScript の型システム比較:AI 時代の「型」は誰のためにあるのか? #frontend_phpcon_do / frontend_phpcon_do_2026
shogogg
1
240
React、まだ楽しくて草
uhyo
7
4k
AI フレンドリーなエラー監視を TypeScript で実現する
shinyaigeek
2
250
正解のないAIプロダクトをどう導くか?dodaが挑む、ユーザーの『本音』を構造化する評価設計と検証のリアル
techtekt
PRO
0
180
Oracle Cloud Infrastructure IaaS 新機能アップデート 2026/3 - 2026/5
oracle4engineer
PRO
1
180
Platform Engineering as a Product: Criteria for Improvement and Multi-Tenant Design
kumorn5s
0
490
Featured
See All Featured
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
180
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
It's Worth the Effort
3n
188
29k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
820
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Building the Perfect Custom Keyboard
takai
2
780
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
560
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
520
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
sira's awesome portfolio website redesign presentation
elsirapls
0
270
Transcript
3ZVTFJ4BKJLJ!TBKJLJY ۀʹ͞Εͨʮྑ͘ͳ͍ܕʯͰߟ͑Δ ʮ5ZQF4DSJQUͷ͠͞ʯ
4BKJ3ZVTFJ4BKJLJ 'SPOUFOE%FWFMPQFSBU$ZCP[V JOD ❤54JO'&5PPMT 𝕏 !TBKJLJY
ޭʹύλʔϯͳ͍͕ ࣦഊʹύλʔϯ͕͋Δ Έ͍ͨͳ֨ݴ͋Δ͡Όͳ͍Ͱ͔͢
5ZQF4DSJQUͰߟ͑Δͱʁ ࣦഊΑ͘ͳ͍ͱ͞Ε͍ͯΔܕه๏ɾଥڠͨ͠ͱ͜Ζ ˣͱ͢Δͱ Ծઆ̍ʮ5ZQF4DSJQUͰଥڠɾϛεͪ͠ΌͬͯΔͱ͜Ζʹύλʔϯ͕͋Δʯ ˣ͞Βʹݴ͑ Ծઆ̎ʮ͜ͷύλʔϯ͕ͦ͜5ZQF4DSJQUͷ͠͞PSݶքͳͷͰʯ
ΞδΣϯμ w ʮۀͰॻ͍ͯ͠·ͬͨྑ͘ͳ͍ܕɾଥڠͨ͠ܕΛऩूɾྨʯͯ͠ɺ w ͦΕΒΛʮύλʔϯԽɾੳ͢Δ͜ͱʯͰɺ w 5ZQF4DSJQUͷ͠͞ͷҰʹഭΖ͏ʂ ͱ͍͏τʔΫͰ͢ʂՃ͑ͯɺ w 5ZQF4DSJQUΛֶͿɾڭ͑Δɾ"*ʹॻ͔ͤΔࡍͷώϯτΛఏڙ͠ɺ
w ༷ʑͳϊϋݟ͕ू·Δͱ͍ͨ͠
ҙࣄ߲⚠ ʮ͜Μͳܕॻ͍ͯΔͳΜͯμϝʂʯͱݴ͏τʔΫͰ͋Γ·ͤΜʂ େࣄ w ୭ͩͬͯΜͰas@ts-ignoreͯ͠ΔΘ͚͡Όͳ͍ w ࣗͩͬͯଟগͨ͜͠ͱ͋ΔͰ͠ΐʁ ڳʹखΛͯͳ͕Β
্ڃऀͷํʹͱͬͯͨΓલͷ͜ͱଟ͍͔͠Ε·ͤΜ͕ɺ w ॳ৺Λࢥ͍ग़ͨ͠Γɺͬͱ͍͍ղܾࡦΛߟ͑ͯΈͨΓ w νʔϜͰͷӡ༻ɾޙਐҭɾ"*͚%PDͳͲ׆͔ͤΔͱ͋͜Δͣ
࣍ ϓϩμΫτͷʮྑ͘ͳ͍ܕʯΛ୳ͯ͠ΈΑ͏ සग़ྫɾ͍͠ྫͷհ ʮྑ͘ͳ͍ܕʯΛྨ͢Δ ݟ͔Βӡ༻
࣍ ϓϩμΫτͷʮྑ͘ͳ͍ܕʯΛ୳ͯ͠ΈΑ͏ සग़ྫɾ͍͠ྫͷհ ʮྑ͘ͳ͍ܕʯΛྨ͢Δ ݟ͔Βӡ༻
Ͳ͜·ͰΛྑ͘ͳ͍ܕͱ͢Δ͔ Ұൠతʹྑ͘ͳ͍ͱ͞ΕΔͷ w anyܕ w asʹΑΔڧ੍Ωϟετ w @ts-ignoreʹΑΔܕνΣοΫͷແࢹ ্ه΄ͲͰͳ͍͕ྑ͘ͳ͍ͱ͞ΕͯΔ w
ࡶͳܕΨʔυؔ
ࠓճରʹͨ͠ίʔυϕʔεͷಛ Ұൠత 3FBDU54ͷҰൠతͳ$MJFOU4JEFΞϓϦߏ ෳࡶͳ'PSNը໘ ೖྗͨ͠σʔλ Ϩίʔυ ͷՄࢹԽ w Ϣʔβʔ͕༷ʑͳ'JFMEͰߏஙͨ͠'PSNΛ࣮ࡍʹಈ࡞ͤ͞Δ w
ೖྗͨ͠σʔλͷৄࡉදࣔҰཡɾάϥϑදࣔɾߜΓࠐΈͳͲ͕Ͱ͖Δ #&͔Βͷσʔλجຊతʹ;PEͰ7BMJEBUJPOͯ͠Δ ͬͯΔਓ͚LJOUPOFͷΞϓϦը໘ͷ3FBDU൛
ࠓճରʹͨ͠ίʔυϕʔεͷಛ ಛघ ͔ͨ͠͠ΒҰൠతͰͳ͍͔͠Εͳ͍ཁ݅ w 'PSN͕ͦΕͳΓʹෳࡶ w fi FMEͷछྨׂ͕ͱଟ͍ छྨҎ্
w ςʔϒϧͷதʹ fi FMEΛஔͰ͖ΔͷͰ̍ஈͷ࠶ىతͳߏ͕͋Δ w Λ+4Ͱॻ͍ͨ6TFS4DSJQU1MVHJOͰΧελϚΠζͰ͖Δػߏ w Ϣʔβʔೖྗͱ#&͔ΒͷσʔλҎ֎ʹ৴པͰ͖ͳ͍ڥք͕͋Δ w ྫ Ϣʔβ͔Β͞Εͨ$BMMCBDLͷݺͼग़͠ͱ͔
୳͠ํ ୳ͤ͞ํ ࠓͷ࣌"*͕͋ΔͷͰੵۃతʹ׆༻͠Α͏ʂ ҎԼΛूதͯ͠ཏతʹ୳ͤͨ͞ w @ts-ignore@ts-expect-error w asΩϟετ as constas
unknown asΛআ֎ w ܕΨʔυؔvalue is X ͋Δఔࡉ͔͘ྨͤ͞Δˠྨ͝ͱʹ࣮ࡍʹίʔυΛݟͯஅ
࣍ ϓϩμΫτͷʮྑ͘ͳ͍ܕʯΛ୳ͯ͠ΈΑ͏ සग़ྫɾ͍͠ྫͷհ ʮྑ͘ͳ͍ܕʯΛྨ͢Δ ݟ͔Βӡ༻
ࠓճ̓ͭසग़ྫΛհ ಛघͳͷɾϨΞ͗͢ΔͷΛൈ͍ͯ̓ͭͷසग़ྫΛհ͢Δ w ͦΕͧΕʹରͯ͠ߟ͑ΒΕΔରࡦซͤͯ ਐΊ͍͢Α͏ʹେ͖̏ͭ͘ͷύλʔϯʹྨͯ͠հ w ͩΜͩΜͱॳาతˠ͍͜͠ʹͳ͍͖ͬͯ·͢ ˞͋͘·ͰࣗνʔϜͷੳ݁ՌͳͷͰѱ͔͠Βͣ
සग़ύλʔϯ ಈతͳڥքͰͷܕམͪ
සग़%0.&WFOUDBUDI F %0.&WFOUCVCCMJOHͷͨΊʹͲ͏ͯ͠ܕ͍ &SSPSΠϯελϯε+4ͷ্༷string͛ΕΔͷͰunknown button.addEventListener('click', (e) => { const target
= e.target as HTMLButtonElement; // ← as }); try { ... } catch (e) { console.error((e as Error).message); // ← as }
සग़%0.&WFOUDBUDI F վળҰखؒͰߜΓࠐΊΔͷͰؤுΖ͏ w %0.&WFOUDVSSFOU5BSHFUΛ͏e instanceofͰOBSSPX w DBUDI F ܕΨʔυΛڞ௨Խͯ͠Α͍
export function isError(value: unknown): value is Error { return value instanceof Error; }
සग़VOLOPXOͰBTͯ͠·͏ ͱΓ͋͑ͣͦΕͬΆ͍ܕ΄͍͠ˠVOLOPXOؚ͕·Ε͍ͯΔBTͪ͠ΌͬͯΔ w ϓϩμΫγϣϯίʔυҎ֎ UFTUͱ͔ ͩͱ͋ͬͨΓ͢Δ վળܕΨʔυΛॻ͜͏ w ϓϩμΫγϣϯίʔυͷ߹ɺͦ͜ΛڥքʹӨڹ͕ٴ͢Δ w
νʔϜ PS"*%PD ͰͪΌΜͱنʹ͢Δͷ͋Γ const value = (config as Record<string, unknown>)[key];
සग़จࣈྻˠ#SBOEFEܕϦςϥϧܕͷݶք ҎԼͷΑ͏ͳΑΓݫ͍͠ߜΓࠐΈσϑΥϧτͰͰ͖ͳ͍ w ͍ΘΏΔ#SBOEFEܕͷΑ͏ͳಠࣗఆٛͷΑΓݫ͍͠ܕ w SVOUJNFͷϝιουجຊจࣈྻϦςϥϧܕ·ͰߜΓࠐΊͳ͍ if (regex.test(rawString)) { return
rawString as DateString; // ← as } const lower = value.toLowerCase(); // → string return lower as LowerValue; // ← as
සग़จࣈྻˠ#SBOEFEܕϦςϥϧܕͷݶք վળܕΨʔυΛॻ͘IFMQFSͷಋೖ w regex.testͳͲܕΨʔυؔΛॻ͔͘͠ͳ͍ w -PXFS$BTFͳͲͷϢʔςΟϦςΟ͕͋ΔIFMQFSʹͪ͠Ό͏ toLower<T extends string>(s: T):
Lowercase<T>
ύλʔϯ̍ͷ·ͱΊ w ೖྗɾΤϥʔͳͲͷಈతڥքͰVOLOPXOͳܕຊདྷΑΓ͍ܕ͕ݱΕΔ w ·ͨඪ४ϝιουͰQSJNJUJWFͳܕҎ্ͷߜΓࠐΈ͍͠ w ͜ͷΑ͏ͳBTʮܕΨʔυPSϔϧύʔݸʯͰ͋Δఔ҆શʹফͤΔ w ͲͪΒ͔ͱ͍͏ͱਓతͳཧ༝͕ଟ͍ w
ʮ໘Ͱʯݟա͝͞Εͨ w ఆͷͣͷͷ͕ͬͯ͠·ͬͨ
සग़ύλʔϯ ಈతͳྻɾ0CKFDUม
සग़"SSBZGJMUFSJODMVEFTJT"SSBZ "SSBZͷඪ४ϝιουͰ͋ΔincludesisArrayͳͲ·ͩෆศ͕͞Δ w JODMVEFTSFBE0OMZ"SSBZͩͱϦςϥϧܕΛڧ੍ w ͔ͱ͍ͬͯɺ௨ৗͷϓϦϛςΟϒͳྻʹ͢ΔͱͨΓલʹܕ͕མͪΔ const STATES = ['a',
'b'] as const; STATES.includes(state); // state: string ͰܕΤϥʔ STATES.includes(state as 'a' | 'b'); // ← ଆͰ as const fieldTypes : string = ['a', 'b']; return fieldTypes.includes(field.type) ? {...field} as Field : null // typestringͷ··ͳͷͰ
සग़"SSBZGJMUFSJODMVEFTJT"SSBZ w JT"SSBZཁૉܕΛ࣋ͨͳ͍ ˠ͜ͷଞɺ"SSBZͷඪ४ϝιου͕Ͳ͜·ͰߜΓࠐΜͰ͘ΕΔ͔ҙ͕ඞཁ Array.isArray(value) ? (value as JsApiUserData[]) :
[]
සग़"SSBZGJMUFSJODMVEFTJT"SSBZ ͱ͍͑গͣͭ͠ਪվળ͞Ε͍ͯΔ w 54Ͱ fi MUFS͕վળ͞Εͨͷͱ͔ʹͳͬͨ w FWFSZಉ༷ʹվળͯ͠Δ [1, 2,
null].filter((x) => x !== null); // ~5.4: (number | null)[] // 5.5~: number[] ← inferred type predicate
සग़"SSBZGJMUFSJODMVEFTJT"SSBZ վળϔϧύʔΛ࡞ΔܕΨʔυΛॻ͘ w JODMVEFTϔϧύʔΛॻ͍ͯͦΕΛ͏Α͏ʹ͢Δ w JT"SSBZ.every(isXXX)Ͱཁૉ୯ҐͷܕΨʔυΛॻ͘ function includesType<T extends readonly
string[]>( arr: T, v: string ): v is T[number] { return arr.includes(v); } const users = Array.isArray(value) && value.every(isUser) ? value : [];
සग़"SSBZGJMUFSJODMVEFTJT"SSBZ վળϥΠϒϥϦͷར༻ߟ͑ͯΈΔ w UTSFTFUͱ͍͏ඪ४ϝιουΑΓڧݻͳIFMQFSΛఏڙ͢ΔϥΠϒϥϦ͋Δ w IUUQTHJUIVCDPNNBUUQPDPDLUTSFTFU import '@total-typescript/ts-reset/array-includes'; const users
= ['matt', 'sofia', 'waqas'] as const; // .includes ୯ʹstringΛظ͢ΔΑ͏ʹͳΔ users.includes('bryan');
සग़0CKFDUGSPN&OUSJFT0CKFDULFZT ߏత෦ܕͷݶքͱͯ͠0CKFDUࠪܥͷϝιουΓ͕ྼԽ͢Δ w ˠܕʹॻ͍͍ͯͳ͍ΩʔΛ࣋ͭPCKFDUಉ͡ܕͱͯ͠௨Γ͏Δ const obj = Object.fromEntries(entries); // ↑
Record<string, V> (ΩʔϦςϥϧ͕ফ͑Δ) Object.keys(record).forEach((k) => { record[k]; // ← k stringɺkeyof typeof record ʹͳΒͳ͍ });
සग़0CKFDUGSPN&OUSJFT0CKFDULFZT վળIFMQFSΛ࡞Γ݈ͭͭશੑࣗͨͪͰอূ͢Δ w GSPN&OUSJFTΩʔͱͷηοτͰอূ͢ΔIFMQFSΛ࡞Γͭͭݕূ w LFZTܕҾ͔Βਪ͢ΔIFMQFS࡞Γͭͭݕূ ͲͪΒʹͤΑɺ҆શੑϢʔβͰอূ͢Δ͔͠ͳ͍ fromEntriesTyped<K, V>(entries: [K,
V][]): Record<K, V> objectKeys<T>(o: T): (keyof T)[] // (தͰ as)
ύλʔϯ̎ͷ·ͱΊ w "SSBZ0CKFDUͷඪ४ϝιουʹؔͯ͠ɺͲ͏ͯ͠୯ମͰղܾ͍͠ w ඪ४ϝιουʹର͢Δઃܭஅ w ߏత෦ܕʹΑΔݶք w ࣗ࡞ϔϧύʔܕΨʔυͰ͋Δఔޮతʹ҆શଆʹͤΔ w
Α͘͏ͷڞ௨Խ͓ͯ͘͠ͱΈΜͳ͕Ըܙʹ༬͔ΕΔ w ͨͩ͠OBSSPXJOHܕΨʔυϢʔβʔ࣍ୈͳ෦͕େ͖͍ͷͰ৻ॏʹ
සग़ύλʔϯ VOJPOͷѻ͍ͷ͠͞
͓͞Β͍EJTDSJNJOBUFEVOJPO 54ʹEJTDSJNJOBUFEVOJPOͱ͍͏ڧྗͳਪػೳ͕͋Δ w VOJPOʹଐ͢Δ0CKFDUʹڞ௨͢ΔϓϩύςΟͰVOJPOΛߜΓࠐΊΔػೳ type Field = | { type:
'TEXT'; value: string } // ← discriminant: type | { type: 'NUMBER'; value: number }; function show(f: Field) { if(f.type === "TEXT") return f.value; // string ʹ narrow }
සग़ରԠ͍ͤͨ͞ΛผʹΈཱͯͯ͠·͏ ຊདྷ̍ର̍ͰରԠ͍ͤͨ͞ܕΛผʑʹ࡞ͯ͠͠·͏ w ޙ͔ΒͦΕͧΕͷରԠؔΛิ͢Δ͜ͱͰ͖ͳ͍ w ܕͱͯ͠୯७ͳੵʹͳͬͯ͠·͏ w const fieldType =
MAPPING[type]; // ผͷࣜͰܭࢉ const fieldValue = convertValue(fieldValue); // ผͷࣜͰܭࢉ const field = { type: jsApiFieldType, value: jsApiValue, } as Field; // Fieldʹas͢Δ͔͠ͳ͘ͳΔ
සग़ରԠ͍ͤͨ͞ΛผʹΈཱͯͯ͠·͏ TUSJOH OVNCFS 5&95 ✅ /6.#&3 ✅ TUSJOH OVNCFS 5&95
✅ ❌ /6.#&3 ❌ ✅ {type:'TEXT',value:string} {type:'NUMBER',value:number} type: 'TEXT' | 'NUMBER', value: string | number ✅ཉ͔ͬͨ͠ܕ EVOJPO ❌࣮ࡍͷܕ ੵ
සग़ରԠ͍ͤͨ͞ΛผʹΈཱͯΔ վળઃܭ্ߏஙΛผʑʹ͠ͳ͍ w GBDUPSZͷΑ͏ͳܗͰରԠ͍ͤͨ͞ͷΛηοτͰߏங͠Δ function createField(typeInput,fieldInput): Field { switch (typeInput)
{ case 'TEXT': return { type: 'TEXT', value: String(fieldInput) }; // ... } }
සग़Ҿͷ6OJPO͔ΒฦΓΛਪͮ͠Β͍ ʮҾͷܕʹԠͯ͡ฦΓͷܕΛม͑ΔؔʯΛδΣωϦοΫʹॻ͚ͳ͍ w 5<UZQF>ͷΑ͏ͳδΣωϦοΫͳJOEFYFEBDDFTTVOJPOʹͳΔ w ˠؔຊମͰʮ5͕'JFME"͔'JFME#͔ʯ͕ఆ·Βͳ͍ function validate<T extends FieldA
| FieldB>( value: unknown, type: T['type'] ): Result<T> { return ok({ value: String(value), type } as T); // ^^^^ ← as }
සग़Ҿͷ6OJPO͔ΒฦΓΛਪͮ͠Β͍ ղܾPWFSMPBEؔͰͳΜͱ͔͢Δ ͱ͍͑ɺύλʔϯ͕૿͑ΔͱΤϥʔ͕গ͠Θ͔Γʹ͍͘ function validate(v: unknown, t: 'TEXT' ): Result<FieldA>;
function validate(v: unknown, t: 'NUMBER'): Result<FieldB>; function validate(v: unknown, t: string): Result<FieldA | FieldB> { return ok({ value: String(v), type: t }); }
සग़ δΣωϦοΫͳҾͰϋϯυϥΛݺͿ ҎԼͷΑ͏ͳΈΛ࡞Δ͜ͱΛ૾ͯ͠΄͍͠ w LFZΛࢦఆͯ͠ϋϯυϥʔؔΛಈతʹొͰ͖ɺݺͼग़͞ΕΔ w ྫFWFOU໊Λࢦఆͯ͠ΠϕϯτϋϯυϥΛొ w LFZʹԠͯ͡ҎԼ͕มΘΔ w
ϋϯυϥʔʹ͢Ҿ w ϋϯυϥʔ͕ฦͣ͢ͷฦΓ
සग़ δΣωϦοΫͳҾͰϋϯυϥΛݺͿ ͬ͘͟Γ࣮ͯ͠ΈΔͱ͜͏ͳΓͦ͏ type Apis = { "getId" :() =>string
.... } const callHandler = async <K extends keyof Apis>({ apiPath, // K apiArgs // Parameters<Apis[K]> }: JsApiCallData[K]) => { const handler = apiHandlers[apiPath]; // Apis[K] return await handler(...apiArgs); // Τϥʔ !! };
සग़ δΣωϦοΫͳҾͰDBMMCBDLΛݺͿ ͳΜͰΤϥʔʹͳͬͯΔͷ͔ w ࣮ΛݟΔͱ w LFZ͔ΒҾ͍͖ͯͨϋϯυϥͷܕ֤ϋϯυϥ ؔ ͷ6OJPOApis[K] w
Ҿϋϯυϥ͕ظ͢ΔҾͷ6OJPOParameters<Apis[K]> w ొ͞Εͨϋϯυϥ͕ड͚͚ΔҾܕશҾܕͷJOUFSTFDUJPO ม w ʮશҾܕͷJOUFSTFDUJPOʯWTʮϋϯυϥ͕ظ͢ΔҾͷ6OJPOʯ w ˠΤϥʔʂ
සग़ δΣωϦοΫͳҾͰDBMMCBDLΛݺͿ ͜Ε0WFSMPBEͳΒղܾग़དྷΔ͕ w "1*Πϕϯτ͕૿͑ͨΒͦͷશ෦0WFSMPBEॻ͘ʁˠݱ࣮త͡Όͳ͍ w ͔ͱ͍ͬͯઃܭͰಀ͛Δͷ͍͠ ͜͜ʹؔͯ͋͠ΔఔׂΓΔඞཁ͕͋Δͷ͔͠Εͳ͍
DPSSFMBUFEVOJPOTʹΑΔվળ VOJPOͷ݁ͼ͖ͭΛҡ࣋͢ΔΑ͏ͳਪͷվળঃʑʹͳ͞Ε͍ͯΔ w W*OEFYFE"DDFTT*OGFSFODF%FTUSVDUVSFE%JTDSJNJOBUFE6OJPO %FQFOEFOU1BSBNFUFST w WPCK<MJUFSBM,FZ>PCK<VOJRVFTZNCPM>ͷOBSSPXJOH w W$POTUBOU*OEFYFE"DDFTTOBSSPXJOH*OGFSSFE5ZQF1SFEJDBUFT w
WδΣωϦοΫผϢχΦϯͷOBSSPXJOH֦ு
ύλʔϯ̏·ͱΊ w σʔλͷ࡞ʹ͓͍ͯEVOJPOʹͰ͖ͳ͍ͷઃܭͷ w ରԠ͍ͤͨ͞ܕৗʹҰॹʹੜ͢Δ͜ͱΛΕͳ͍ w ޙͷ6OJPOͷਪͷϔϧύʔΨʔυͰղܾ͕͍͠ w ಛʹؔͷབྷΉͷɾϋϯυϥʔύλʔϯͳͲ͍͠ w
গͣͭ͠վળ͍ͯͬͯ͠ΔͷͰࠓޙʹظ
࣍ ϓϩμΫτͷʮྑ͘ͳ͍ܕʯΛ୳ͯ͠ΈΑ͏ සग़ྫɾ͍͠ྫͷհ ʮྑ͘ͳ͍ܕʯΛྨ͢Δ ݟ͔Βӡ༻
ྨͷ࣠Λߟ͑Δ ࠓճʮͲ͏ରࡦ͢Δ͔ʯΛͱʹҎԼͷ̎ͭͷ࣠Ͱߟ͑ͯΈΔ w ڥքͰى͖ͯΔͷ͔෦Ͱى͖ͯΔͷ͔ w ֎෦ͱͷڥքʹΑΔͷWT෦Ͱىͬͯ͜͠·ͬͯΔ͜ͱ w ҆શݍʹԡͤ͠Δ͔ w ܕΨʔυϔϧύʔͳͲͰ҆શݍʹԡͤ͠ΔWT͍͠
ࠓճհͨ͠ύλʔϯΛྨͯ͠ΈΔ ԡͤ͠Δ ԡͤ͠ͳ͍ ڥք༝དྷ ෦༝དྷ " ࣮͋·Γͳ͍ $ # w
%0.&WFOUDBUDI w จࣈྻˠ#SBOEFE w VOLOXPOͰͷBT w fi MUFSJODMVEFT wGSPN&OUSJFT w%JTDSJNJOBUFEVOJPOͷੜ w ҾʹԠͨ͡ฦΓਪ w δΣωϦοΫͳҾͱϋϯυϥʔ
ͦΕͧΕͷॲํᝦ "ڥք༝དྷºԡͤ͠Δ w ˠεΩʔϚ ;PE ΛؚΉܕΨʔυ͕ใΘΕΔ w ˠʮܕΨʔυΛॻ͚ΔॴͰॻ͘ʯΛνʔϜنʹ #෦ىҼºԡͤ͠Δ w
ˠνʔϜͰܕϔϧύʔɾܕΨʔυूΛ࣋ͭ w ˠઃܭूͱ%3:ͷτϨʔυΦϑݟۃΊΔඞཁ͋Γ
ͦΕͧΕͷॲํᝦ $෦ىҼºԡͤ͠ͳ͍ w ͋ΔఔఘΊΔ͔͠ͳ͍͕ w ˠہॴͰBT@ts-expect-error ཧ༝Λίϝϯτ w ˠ54ͷਐԽΛ͏ DPSSFMBUFEVOJPOT
ରࡦΘ͔͚ͬͨͲ Ͳ͏ͬͨΒؾ͚ͮΔʁ
ةͳ͍κʔϯͷΞϯςφΛݚ͗·͢ ࠓͦ͜ʮ͜͜ةͳͦ͏ʯͱ͍͏ײ֮େࣄ w ίʔυϨϏϡʔͰͷࢦఠ"*ͷࢦࣔ w νʔϜͷڭҭɾΦϯϘʔσΟϯά w ͕ࣗࡶͳBTJHOPSFΛॻ͖ͦ͏ͳ࣌ͷϒϨʔΩ w ͦͦઃܭ͔࣌Β54ʹ༏͍͠σʔλʹͳͬͯΔ͔
ˠઌճΓͰ͖Δ΄Ͳ҆શͳӡ༻ɾઃܭʹͭͳ͕Δ
ࠓճͷੳ͔ΒಘΒΕͨνΣοΫϦετ ͜ΕΒʹ֘͢ΔίʔυΛॻ͍ͯΔɾݟͨ߹ཁҙαΠϯ🚨 ☑︎ ֎෦ͱͷڥքΛލ͍Ͱ͍Δ͔ʁ ☑︎ ྻɾΦϒδΣΫτͷಈతมΛܦ༝͍ͯ͠Δ͔ʁ ☑︎ UZQFͱWBMVFΛผͷࣜͰΈཱ͍ͯͯͳ͍͔ ☑︎
͏ଆͷܕΛؔͰδΣωϦοΫͳܕ͔Β֬ఆͤ͞Α͏ͱͯ͠Δʁ ☑︎ ಉ͡ଥڠ͕܁Γฦ͞Ε͍ͯͳ͍͔ ˞ͪΖΜ͜Ε͕શͯͰͳ͍
࣍ ϓϩμΫτͷʮྑ͘ͳ͍ܕʯΛ୳ͯ͠ΈΑ͏ සग़ྫɾ͍͠ྫͷհ ʮྑ͘ͳ͍ܕʯΛྨ͢Δ ӡ༻
ͦ͏͍ͬͯ Ͳ͏ͬͯӡ༻͢Δʁ
ӡ༻ʹ͚ͯ MJOUͰنԽ͢Δ w CBOUTDPNNFOUSVMF @ts-expect-erroSͰίϝϯτΛڧ੍ ΨΠυϥΠϯʹ໌ه w ྫ 'PSN fi
FMEมGBDUPSZʹू͢Δ͜ͱ ఆظతͳ୨Է͠ w QSPEVDUJPOͷas@ts-ignoreΛʙͰ୨Է͠
JO"*$PEFJOH "*Կ͠ͳ͍ͱಉ͡ଥڠΛ࠶ੜ࢈͍͢͠ w ؾ͍ͮͨΒas@ts-ignore͕૿͑ͯΔͦΜͳܦݧ͋ΔͷͰʁ نͱͯ͠ॻ͍͓ͯ͘ͱྑ͍ w ࠓճͷΑ͏ͳνΣοΫϦετΛʮةͳ͍໘ʯͱͯ͠໌ࣔ w Մೳͳճආࡦɾվળ໌͓ࣔͯ͘͠ w
"*͕ଥڠ͢Δ࣌ཧ༝Λग़ྗͤ͞Δ
୨Է͠"*ʹͤ͞Α͏🤖 ࠓͷUBMLͷωλ"*ʹίʔυϕʔεΛੳͤͨ͞Ռ͔Βελʔτ ͱݴ͏͜ͱΈΜͳ؆୯ʹ࢝ΊΒΕΔʂ w "*ʹͤΔasɾ@ts-ignoreͷϦετΞοϓύλʔϯผͷࣗಈྨ w ਓؒ XJUI"* ͕அ54ͷݶք͔PSઃܭͷ͔༏ઌߴ͍͔ ˠු্ͨ͠ଥڠΛվળνέοτ🎫
࠶ܝ୳͠ํ ୳ͤ͞ํ ࠓͷ࣌"*͕͋ΔͷͰੵۃతʹ׆༻͠Α͏ʂ ҎԼΛूதͯ͠ཏతʹ୳ͤͨ͞ w @ts-ignore@ts-expect-error w BTΩϟετ as constas
unknown asΛআ֎ w ܕΨʔυؔvalue is X ͋Δఔࡉ͔͘ྨͤ͞Δˠྨ͝ͱʹ࣮ࢪʹίʔυΛݟͯஅ
·ͱΊ ۀͷʮྑ͘ͳ͍ܕʯʹύλʔϯ͕͋Δ w ͨ͘͞Μ͋ͬͯେύλʔϯʹऩ·Δ w ࠓճ ઃܭͷΈɺ54ͷදݱྗͷݶքͩͬͨ ͦΕͧΕͷύλʔϯΛੳ͢Δͱ w ઃܭͷ͍͠ͱ͜Ζ54ͷݶքɾ54ͷࠓ·Ͱͱ͜Ε͔ΒΛΕΔ
w νʔϜϝϯόʔ"*ͷྐʹͳΔ օ͞Μͥͻऩूɾੳͯ͠ΈΑ͏ʂ
࠷ޙʹ
͔ͤͬ͘ʮϦΞϧʯͷ ΧϯϑΝϨϯεʹ͍Δͷ͔ͩΒ
օ͞Μͷࢥ͍ݟฉ͖͍ͨ ͖ͬͱௌ͍ͯΔΈͳ͞Μ͍ΖΜͳ͜ͱΛࢥͬͯ͘Εͨͣ w ʮͦΕ࣮ͬͱ্ख͘ղܾ͢Δํ๏͋ͬͯʯ w ʮ54Ҏ֎ͷଞͷݴޠͩͱ͕ͯͨͭ͠͏·͍͘͘ΜͰ͢Αʯ w ʮҎલ͜ͷJTTVFͰͯͨ͠ͷͰղܾ͢Δ͔͠Ε·ͤΜΑʁʯ w ʮΑ͋͘ΔύλʔϯͰ͜͏͍͏ͷ͋Γ·ͤΜʁʯ
w ʮ͏ͪͰ͜Μͳӡ༻Ͱ͍Ͱ·͢Αʙʯ w FUD
એϒʔεʹ͍·͢ʂ ฐࣾαΠϘζ(PMEεϙϯαʔͱͯ͠ϒʔεΛग़͍ͯ͠·͢ʂ ͥͻ༡ͼʹ͖͍࣭ͯͩ͘͞ɾ͓8FMDPNFʂ
օ༷҆͝શʹʂ 3ZVTFJ4BKJLJ!TBKJLJY ܕ