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 の class を使い倒す
Search
Takuya Eguchi (egch)
July 22, 2024
Technology
56
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
TypeScript の class を使い倒す
Takuya Eguchi (egch)
July 22, 2024
More Decks by Takuya Eguchi (egch)
See All by Takuya Eguchi (egch)
Next.js に疲れた私は Vue3 に癒やされた
egch
0
330
Secure な UX のために Content Security Policy について知っておこう
egch
0
59
package.json がすごい
egch
0
150
Nuxt.js のインスタンスライフサイクル総点検
egch
0
420
Webエンジニアのデザイン実装との付き合い方
egch
0
320
20200528 - GCPでもサーバーレスでRubyりたい!
egch
0
140
VeeValidate の"穴"を踏み抜いてしまった
egch
1
920
継続的に楽しくプログラミングするには - 2018/11/3 Rails Girls Sendai
egch
0
120
Other Decks in Technology
See All in Technology
サプライチェーンセキュリティの空白地帯 - 信頼できる”依存性”の未来を考える
rung
PRO
2
800
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
160
機械学習を「社会実装」するということ 2026年夏版 / Social Implementation of Machine Learning June 2026 Version
moepy_stats
2
530
個人の発見を、組織の知恵に 〜生成AI活用を"探索"から"組織の仕組み"へ〜
kintotechdev
3
1.1k
[モダンアプリ勉強会]今更聞けないGit/GitHub入門
tsukuboshi
0
310
Platform Engineering as a Product: Criteria for Improvement and Multi-Tenant Design
kumorn5s
0
530
「嘘をつくテスト」の失敗例から学ぶ 良いテストコード #frontend_phpcon_do
asumikam
0
590
新しいVibe Codingと”自走”について
watany
5
250
Microsoft Build Keynoteふりかえり
tomokusaba
0
120
ITエンジニアを取り巻く環境とキャリアパス / A career path for Japanese IT engineers
takatama
4
1.8k
関西に縁あるMicrosoft MVPsが語るCopilotの未来
kasada
0
1.2k
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
280
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.9k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
360
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
180
sira's awesome portfolio website redesign presentation
elsirapls
0
270
Optimizing for Happiness
mojombo
378
71k
Abbi's Birthday
coloredviolet
2
8k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
560
Designing for Performance
lara
611
70k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
Transcript
TypeScript の Class を使い倒す 💪 2024/07/22 Sendai Front-End User Group
自己紹介 江口 拓弥 SFEUG 運営メンバーの1人 2018年に東京から仙台に移住 2019年から複数プロジェクトの新規事業開発やってます 1児の父です👶 akathea_
😢 こんなことありませんか? 1. API の response 型を バックエンドとフロントエンド 両方で定義するのが辛い 2.
フロントエンドでもバックエンドでも 値のバリデーション処理を書くのが辛い
A. GraphQL
おわり
✋ ちょっとまった!
Monorepo はどうだろう? @sick-project @sick-project/dto @sick-project/next @sick-project/nest get-foo.ts post-bar.ts
パッケージ module moduleResolution ESNext Bundler CommonJS NodeNext (target: ES2021から) @sick-project/dto
? ? このアイデアの問題点 型の提供だけならそれでよいが、 NestJS 側で swagger や class-validator 等を使うとき DTO は class として定義が必要 → tsconfig が異なるためどうビルドすればいいのか...
💡 マルチバンドルすればいいのでは?
前回の LT で話した内容を参考に https://speakerdeck.com/akagire/package-dot-json-gasugoi
こんな感じを妄想🤔 @sick-project @sick-project/dto @sick-project/next @sick-project/nest dist get-foo.js post-bar.js src get-foo.ts
post-bar.ts es get-foo.js post-bar.js type get-foo.d.ts post-bar.d.ts
パッケージ module moduleResolution ESNext Bundler CommonJS NodeNext (target: ES2021から) @sick-project/dto
CommonJS NodeNext tsconfig の設定は NestJS に寄せた
package.json と tsconfig.json を環境ごとに用意... @sick-project/dto src es dist package.json tsconfig.json
tsconfig.es.json { "exports": { ".": { "browser": "./es/index.js", "default": "./dist/index.js" } }, "types": "./dist/index.d.ts", "scripts": { "build:backend": "tsc -p tsconfig.json", "build:frontend": "tsc -p tsconfig.es.json" } } { "compilerOptions": { “module”: “CommonJS”, “target”: “ES2021” } } { "compilerOptions": { “module”: “ESNext”, “moduleResolution”: “NodeNext” } } ※tsconfigはだいぶ端折ってます
🎉 import できた! @sick-project/next/fetchFoo.ts import type { GetFoo } from
‘@sick-project/dto’; // 略 const res = await fetch(‘/foo’); const body: GetFoo = await res.body(); @sick-project/nest/foo-controller.ts import type { GetFoo } from ‘@sick-project/dto’; // 略 res.status(200).json<GetFoo>({ message: ‘foo’ });
😢 と、思っていたのか
es 向けビルド結果に decorator が混入 var __decorate = // 定義は略 import
{ ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty } from 'class-validator'; var GetFoo = /** @class */ (function () { function GetFoo () { } __decorate([ ApiProperty({ // description 等... }) IsNotEmpty() ], GetFoo.prototype, “type”, void 0); return GetFoo; }()); export { GetFoo }; この影響でフロントエンド環境に @nestjs/swagger, class-validator を入れないとビルドでエラー(ノ∀` ) →使いもしないのにインスコが必要で バンドルサイズ爆増
Strip Decorator https://www.npmjs.com/package/strip-decorators
ビルド結果 import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty
} from 'class-validator'; var GetFoo = /** @class */ (function () { function GetFoo () { } return GetFoo; }()); export { GetFoo }; 😢 decorator は消えたが、 import 文は消えてない dto の package.json へ “sideEffect”: false を指定で tree shaking されるが、 フロント側に @nestjs/swagger を install してないとビルドが通らない状況は変わらない class-validator をフロントエンドのリクエスト時のバリデーションで利用できなくなる
Strip Decorator の中身を覗いてみると... 👀
🤔 TypeScript Compiler API を使ってた https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
TypeScript のトランスパイル処理をイジることができる サンプルとして、 • ES6 から d.ts ファイルの生成 • AST
を舐めて自作 linter を作る • moduleResolution のカスタマイズ などの魔改造コードが掲載されている
💡 これ使って 任意の decorator と import だけ 除去できるのでは?
😎 できた https://gist.github.com/akagire/38314038316c37afe115fd1025337af1
カスタムビルドの結果 Swagger に関する decorator だけ消すことができた →これでフロントエンドに @nestjs/swagger が不要になった! var __decorate
= // 定義は略 import { IsNotEmpty } from 'class-validator'; // 残ってる! var GetFoo = /** @class */ (function () { function GetFoo () { } __decorate([ IsNotEmpty() // 残ってる! ], GetFoo.prototype, “type”, void 0); return GetFoo; }()); export { GetFoo };
🤔 ・Compiler API は disclaimer にある通り なので、production で利用するのは心配 ・やりすぎてる感、やや難易度が高い印象 🎉
package.json × TypeScript × Compiler API を 組み合わせることで、互換性のない パッケージ間でも class をいい感じに共有! まとめ Keep in mind that this is not yet a stable API 💡 ・型共有の選択肢として十分ありだと思った ・フロントエンドのバンドルサイズ削減に 使えるかもしれない
おわり