Upgrade to Pro — share decks privately, control downloads, hide ads and more …

T3 Stack and TypeScript ecosystem

T3 Stack and TypeScript ecosystem

Yosuke Kurami

January 18, 2023
Tweet

More Decks by Yosuke Kurami

Other Decks in Programming

Transcript

  1. T3 Λࢧ͑ΔTypeScript
    by @Quramy
    #techfeed_experts_night 2023.1.18

    View Slide

  2. T3 Λࢧ͑ΔTypeScript
    by @Quramy
    #techfeed_experts_night 2023.1.18
    ͷΤίγεςϜ

    View Slide

  3. About me
    - Twitter / GitHub: @Quramy
    - Web Developer
    (Node.js / Ruby on Rails ͷׂ߹͕ߴΊ)
    - Techfeed Expert (TypeScript)

    View Slide

  4. T3 Stack
    - 2022 ೥ ʹެ։͞Εͨ Web ΞϓϦέʔγϣϯ։ൃελοΫ
    - Backend / Frontend ૒ํΛ TypeScript Ͱهड़͢ΔલఏͷϥΠϒϥϦߏ

    - https://github.com/t3-oss/create-t3-app

    View Slide

  5. View Slide

  6. View Slide

  7. T3 Axiom:
    Typesafety is not optional
    The stated goal of Create T3 App is to provide the quickest
    way to start a new full-stack, typesafe web application.
    We take typesafety seriously in these parts as it improves our
    productivity and helps us ship fewer bugs.
    Any decision that compromises the typesafe nature of Create
    T3 App is a decision that should be made in a different
    project.
    https://create.t3.gg/en/introduction#typesafety-isnt-optional

    View Slide

  8. Typesafe ͱ͸ʁ
    - "Typesafe" ͸ͲͷΑ͏ͳঢ়ଶΛࢦ͢ͷͩΖ͏͔
    - ʮ҆શੑʯ͕ίϯςΩετʹΑͬͯఆٛͷҟͳΔ༻ޠ
    - e.g. نఆ͞Εͨશͯͷܕʹ͍ͭͯະఆٛಈ࡞͕ଘࡏ͠ͳ͍͜ͱΛ
    Typesafe ͱݺͿͳΒ͹ɺ JavaScript ͸ܕʹ͍ͭͯ҆શͳݴޠ

    View Slide

  9. Typesafe ͱ͸ʁ
    - Question:
    ࣍ͷ TypeScript ίʔυ͸ TypesafeͰ͔͢ʁ
    - TypeScript Ͱ͋ͬͯ΋҆શͱ͸ݶΒͳ͍
    - API Ϩεϙϯεͷܕ͕ any, fetch URL ΍ύϥϝʔλ෇༩ํ๏
    - զʑʹͱͬͯͷ Typesafe :
    ΞϓϦέʔγϣϯʹޡΓ͕ࠞೖ͢ΔՄೳੑ͕੩తʹۃখԽ͞Ε͍ͯΔঢ়ଶ
    const product = await fetch(`/api/products/1234`).then(res => res.json())

    View Slide

  10. The unknown
    - TypeScript͕༧ଌͣ͠Β͍ྖҬ
    - JavaScriptҎ֎ͷΤίγεςϜͱͷ࿈ܞ
    - e.g. API req/res, database access,
    CSS / HTML template, etc...
    - ೗ԿʹunknownΛݮΒ͔͕͢DX޲্ͷ伴
    https://speakerdeck.com/quramy/extends-developer-experience?slide=13 ΑΓ࠶ܝ

    View Slide

  11. How T3 tackle unknown
    Browser JS Node.js
    Internet
    Rendering
    Engine
    Database
    tRPC Prisma
    TSX (React)

    View Slide

  12. tRPC
    - TypeScript ʹΑΔ Remote Procedure Call Λ࣮ݱ͢ΔϥΠϒϥϦ
    - ϑϧελοΫ TypeScript ։ൃʹಛԽ
    GraphQL ΍ Open API ͕ݴޠඇґଘͰ͋Δ఺ʹ͓͍ͯɺੑ࣭͕ҟͳΔ
    - Zod ΤίγεςϜͷҰͭ
    - T3 ( Next.js ) Ͱ࢖͏৔߹: react-query ΛϥϯλΠϜʹ༻͍Δ

    View Slide

  13. export const ProductDetail = () => {
    const { data, isFetching } = trpc.productDetail.useQuery({ id: "1234" })
    if (isFetching || !data) return Loading...
    return (

    Product name: {data.name}

    )
    }
    Browser JS
    Node.js
    const getContext = () => ({ prisma })
    const { router, procedure } = initTRPC.context().create()
    const productDetail = procedure
    .input(z.object({ id: z.string() }))
    .query(async ({ ctx: { prisma }, input: { id } }) => {
    const result = await prisma.product.findUnique({ where: { id } })
    return {
    id: result.id,
    name: result.name,
    price: result.price,
    }
    })
    export const appRouter = router({
    productDetail,
    })
    export type AppRouter = typeof appRouter
    Internet
    Inference Inference

    View Slide

  14. tRPC ʹ͓͚Δ Typesafe
    - ϓϩγʔδϟ (= ؔ਺) ͷίʔυ͔ΒΫϥΠΞϯτܕఆٛΛਪ࿦͢Δ
    Zod ΋಺෦ DSL ͱͯ͠ར༻͞Ε͍ͯΔ
    - Mapped types / Conditional types Λ༻͍ͨܕਪ࿦
    https://github.com/trpc/trpc/blob/b18b8134eb666e2c88fe3c245ebf78e7c9817859/packages/server/src/
    core/types.ts#L53-L66

    View Slide

  15. Prisma
    - 2019 ೥ࠒʹొ৔ͨ͠ TypeScript ( Node.js ) ༻ͷ ORM
    ※ લ਎Ͱ͋ΔGraphQLϕʔεͷ Prisma v1 ͱ͸ผ෺ͱଊ͑ͯΑ͍
    - Typesafe ͳΫΤϦͷهड़͕Մೳ
    - ֤छRDB ( MySQL / PostgreSQL / SQLite / SQLServer) ʹରԠ
    - ϚΠάϨʔγϣϯ༻ͷ CLI ΋෇ଐ͢Δ
    - ϥϯλΠϜͰಈ࡞͢ΔΫΤϦΤϯδϯ͸ Rust ੡

    View Slide

  16. const productDetail = procedure
    .input(z.object({ id: z.string() }))
    .query(async ({ ctx: { prisma }, input: { id } }) => {
    const result = await prisma.product.findUnique({ where: { id } })
    return {
    id: result.id,
    name: result.name,
    price: result.price,
    }
    })
    Node.js
    Database
    generator client {
    provider = "prisma-client-js"
    }
    datasource db {
    provider = "postgresql"
    url = env("DATABASE_URL")
    }
    model Product {
    id String @id @default(cuid())
    name String @unique
    price Int
    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt
    }
    Generate
    Import
    schema.prisma (DSL)
    Prisma Client .js / .d.ts file

    View Slide

  17. Prisma ͱ TypeScript
    - ֎෦DSL (Schema) ͔ΒɺTypeScript ιʔείʔυΛࣗಈੜ੒͢Δઓུ
    - ͜ͷҙຯͰ͸ɺGraphQL ΍ Open API ͷΤίγεςϜʹ͍ۙ͠
    - ίʔυੜ੒ʹ CLI ࣮ߦ͕ඞཁͱͳΔ͕ɺੜ੒෺ࣗମ͸ಡΈ΍͍͢
    - tRPC ΍ Zod ͷ৔߹, ਪ࿦աఔͷܕ৘ใ͕ෳࡶͰܕύζϧΈ͕ڧ͍

    View Slide

  18. ·ͱΊ

    View Slide

  19. ·ͱΊ
    - T3 Axiom Ͱ͋Δ "Typesafety is not optional" Λେࣄʹ͠·͠ΐ͏
    - Typesafety ΛಘΔ͜ͱ ≒ unknown Λ౗͢͜ͱ
    - TypeScript ܕਪ࿦ύλʔϯ: Zod, tRPC, react-hook-form, etc...
    - .ts ίʔυࣗಈੜ੒ύλʔϯ: Prisma, Relay, graphql-codegen, etc...

    View Slide

  20. ͓·͚
    - TypeScript ϑϨϯυϦͳελοΫ͸ T3 Ҏલʹ΋৭ʑ͋Δ͕ɺͲ͜ʹ৽
    نੑ͕͋Δͷ͔
    - tRPC ؚΊɺZod Λத৺ʹਾ͑ͨΤίγεςϜ͕৳ͼ͍ͯΔ
    https://2022.stateofjs.com/en-US/other-tools/

    View Slide