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

TSConf 2019: Don't Break the Contract: Keep Consistency with Full Stack Type Safety

TSConf 2019: Don't Break the Contract: Keep Consistency with Full Stack Type Safety

We’ve seen the Web evolve from blue hyperlink text to complex web applications. In modern web application development, not only JavaScript is allowing our teams to build richer user experiences in the front-end, but Node.js has also emerged as the go-to back-end technology of choice.

While this stack is flexible and fun to program in, building and maintaining internal APIs can be an unpleasant experience. Have you ever had a front-end bug because there was an unexpected change in the back-end? In this talk, we’ll explore how TypeScript can help our development teams to reduce these bugs by extending the type system from the back-end to the front-end.

We'll discover how types bring benefits to an application in terms of maintainability, robustness, and clean code that can be easily refactored in the future.

Fernanda Andrade

October 11, 2019
Tweet

More Decks by Fernanda Andrade

Other Decks in Programming

Transcript

  1. { "references": [ { "path": "client" }, { "path": "server"

    }, { "path": "shared-types" } ], "files": [] } tsconfig.json (Solution)
  2. { "extends": "../tsconfig.base.json", "compilerOptions": { ... } }, "references": [

    { "path": "../shared-types" } ] } tsconfig.json (client)
  3. declare namespace MyApi { type Status = "available" | "unavailable";

    interface User { age: number; id: number; name: string; status: Status; } interface GetUsers { (): Promise<User[]>; } ... index.d.ts (shared-types)
  4. const getUsersReq = (req, res) => { res.json(getUsersFn()); }; const

    getUsersFn: GetUsers = function() { const users: User[] = [{ age: 15, id: 10, name: "Tess", status: "available" }]; return Promise.resolve(users); }; users.ts (server)
  5. declare namespace MyApi { type Status = "available" | "unavailable";

    interface User { age: number; id: number; name: string; status: Status; } interface GetUsers { (): Promise<User[]>; } ... index.d.ts (shared-types)
  6. const getUsersReq = (req, res) => { res.json(getUsersFn()); }; const

    getUsersFn: GetUsers = function() { const users: User[] = [{ age: 15, id: 10, name: "Tess", status: "available" }]; return Promise.resolve(users); }; users.ts (server)
  7. declare namespace MyApi { type Status = "available" | "unavailable";

    interface User { age: number; id: number; name: string; status: Status; } interface GetUsers { (): Promise<User[]>; } ... index.d.ts (shared-types)
  8. const getUsersReq = (req, res) => { res.json(getUsersFn()); }; const

    getUsersFn: GetUsers = function() { const users: User[] = [{ age: 15, id: 10, name: "Tess", status: "available" }]; return Promise.resolve(users); }; users.ts (server)
  9. index.d.ts (shared-types) declare namespace MyApi { type Status = "available"

    | "unavailable"; interface User { age: number; id: number; nickname: string; status: Status; } ...