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
8.4k
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
36
本当はややこしい日時のFormatPattern
sajikix
0
410
tpac_study (2026)
sajikix
0
350
It’s “Time” to use Temporal
sajikix
3
720
ユーザーが作成したコードをブラウザ上で安全に実行できる Plugin システムへのアプローチ
sajikix
1
880
Branded Typesで日時の複雑さと戦う
sajikix
4
1.2k
推しProposalと広がる夢~Intl.MessageFormatとDomLocalization~
sajikix
2
840
自作JSエンジンに推しプロポーザルを実装したい!
sajikix
1
380
Lookback TypeScript ESM support and what should we do now.
sajikix
5
840
Other Decks in Technology
See All in Technology
絵ではじめるKubernetesセキュリティ
aoi1
4
670
EventBridge に「合流」はない ― サーバーレスのワークフローを育てるということ / No Join in EventBridge
yusukeshimizu
2
150
ユーザー価値を届け続けるためにウォンテッドリーが大切にしている文化
kotaminato
0
180
LLMに渡さなかった仕事
nanaism
0
830
銀行勘定系システムにおける開発プロセス刷新×AIによる環境モダナイゼーション / Development Process Transformation and AI-Driven Environment Modernization
muit
1
2.3k
おい、エージェントを使って終わらせろ
nwiizo
1
680
越境するなら専門用語を使うな高校校歌 / If you wanna cross border, you shouldn't use jargon
vtryo
0
140
すぐできる衛星通信対応 あとは山奥に行くだけ
tatetate55
0
130
俺の仕事は AIに奪われないし、たぶんその BIも要らない
hikaruri
0
520
アプリログインとWeb認証基盤をつなぐ ASWebAuthenticationSession 作法
shimastripe
1
340
JSONataとAWS Step Functionsで目指すRuntimelessな世界
mu7889yoon
0
180
Claude Code本って、 読む必要あるの?
oikon48
2
480
Featured
See All Featured
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
510
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
280
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
エンジニアに許された特別な時間の終わり
watany
109
250k
The Limits of Empathy - UXLibs8
cassininazir
1
680
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
240
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
203
76k
Become a Pro
speakerdeck
PRO
31
6.3k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
520
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Faster Mobile Websites
deanohume
310
32k
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 ܕ