Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
業務に残された「良くない型」で考える「TypeScriptの難しさ」
Search
Saji
May 21, 2026
Technology
9.6k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
業務に残された「良くない型」で考える「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
Intlのここ数年とこれから
sajikix
0
54
本当はややこしい日時のFormatPattern
sajikix
0
460
tpac_study (2026)
sajikix
0
390
It’s “Time” to use Temporal
sajikix
3
840
ユーザーが作成したコードをブラウザ上で安全に実行できる Plugin システムへのアプローチ
sajikix
1
910
Branded Typesで日時の複雑さと戦う
sajikix
4
1.3k
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
2
880
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
400
Lookback TypeScript ESM support and what should we do now.
sajikix
5
850
Other Decks in Technology
See All in Technology
【Oracle AI SPOTLIGHT ウェビナー】事例から見る!なぜOCIが選ばれたのか ― AI時代のクラウド戦略を紐解く ―
oracle4engineer
PRO
1
120
VLA-JEPA: Enhancing Vision-Language-Action Models with Latent World Models
takmin
0
350
GitHub、使う?使わない?
happysamurai294
0
110
クラウドサインを止めずに Nuxt へ 次の10年のために先に決めたこと
bengo4com
1
170
(swiftc) NonCopyableとライフタイム修飾子
teamhimeh
0
150
Flutter Widget Previewerで始めるUIプレビューとVRTの自動化
sakusaku3939
0
150
バイブコーディングの特徴と「コケて直す」ループ
happysamurai294
0
110
AWS Continuum for Penetration Testing に Deep Dive してみる
asanoharuki
2
1.4k
Draft AIエージェントの トークン消費を最小化する 8つの原則
kinopeee
6
1.8k
AIで選択肢が広がった組織設計の理想と現実
konifar
15
6.6k
アカウント統制の健康診断
kenichinakamura
1
210
キヨさん、67歳。AIコーディングエージェントに挑む
happysamurai294
0
110
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
500
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
2
330
The Pragmatic Product Professional
lauravandoore
37
7.5k
Six Lessons from altMBA
skipperchong
29
4.5k
We Are The Robots
honzajavorek
0
410
Discover your Explorer Soul
emna__ayadi
2
1.3k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.8k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
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 ܕ