Save 37% off PRO during our Black Friday Sale! »

Type safety initiatives for LINE Securities front-end

Type safety initiatives for LINE Securities front-end

Eebedc2ee7ff95ffb9d9102c6d4a065c?s=128

LINE DevDay 2020

November 26, 2020
Tweet

Transcript

  1. None
  2. About Speaker Ryota Suzuki a.k.a. @uhyo_ › Front-end engineer working

    on LINE Securities (LINE証券) › TypeScript Lover › Lots of TypeScript articles on Qiita and blog › Several contributions to TypeScript › Also writing a TypeScript book! Twitter: @uhyo_ GitHub: @uhyo Qiita: @uhyo Blog: https://blog.uhy.ooo/
  3. None
  4. Development of LINE Securities › TypeScript + React › 150,000+

    LoC of TypeScript › 10+ front-end engineers working on the same project
  5. Our MUSTs and Type Safety We MUST keep the service

    up We MUST develop fast We MUST write sustainable code
  6. Our MUSTs and Type Safety Types help reduce bugs Types

    accelerate our development Types contribute to code design
  7. Agenda › XLT: Types for i18n Utils › A Custom

    typescript-eslint Rule › Gradual adoption of noImplicitAny
  8. XLT: Types for i18n Utils

  9. What is XLT? › In-house i18n system › Admin for

    text management and API for exporting text › XLT = Cross-Language Translation Tool
  10. Our XLT Workflow › 1. Download text data from XLT

    system › 2. Commit data and use it › (We don’t query data at runtime; it’s not CMS. Rather, it’s for managing text separately from source code)
  11. Our Use of XLT › Query text with xlt function

    › Supports partial application!
  12. Type Safety & DX of XLT › Of course, fully

    type-safe! › Auto completion is there too!
  13. Code Generation for XLT › We generate a large type

    that accepts all possible keys (including partial ones) › Runtime code is fixed TS 4.1’s template literal types might help? !
  14. Code Generation is Automated!

  15. Bonus: Splitting Runtime Data with Babel

  16. A Custom typescript-eslint Rule

  17. Background: A Common Pattern with JSX › The {cond &&

    <Something />} pattern › Show <Something /> if cond › Show nothing if not cond (React does not render false) › Simpler than cond ? … : null
  18. Actual Code with Bug › noticeTotal is a number |

    undefined › What if noticeTotal is 0?
  19. Actual Code with Bug

  20. Actual Code with Bug

  21. Summary of the Problem › 0 && … is evaluated

    to 0 › React renders 0 ! › In general, number && element is very bug-prone › We want to forbid this pattern
  22. Our Solution: Custom typescript-eslint Rule @linecorp/jsx-no-number-andand (sorry, not OSS!)

  23. Making a typescript-eslint Rule › Get a TypeChecker instance from

    custom parser › This provides us type information of expressions
  24. Making a typescript-eslint Rule › Query && expressions at JSX

    child positions › Get the type of the left operand › If number is included, emit a lint error
  25. Gradual Adoption of noImplicitAny

  26. What is noImplicitAny? › Compiler option to forbid parameters without

    type annotation › Comes with other stricter checks › Without this option, these parameters get the any type! !
  27. Let’s Enable noImplicitAny › Advice from me: always enable noImplicitAny

    when you start a new project › tsc --init already does so!
  28. The any Nightmare › The any type propagates ! ›

    Disaster to type safety › The any type disables nearly all compile errors ☠
  29. The Problem › We did not have time to solve

    this all at once › QA would be impratically high-cost › Major part of our codebase did not enable noImplicitAny !
  30. Why We didn’t? › Our project used TypeScript from start

    › But a lot of code was copied from JavaScript project › We didn’t know TypeScript very well, so just chose the easiest way to proceed with it !
  31. 0 100 200 300 400 500 600 0 20000 40000

    60000 80000 100000 120000 140000 160000 2018/07 2018/11 2019/03 2019/07 2019/11 2020/03 2020/07 noImplicitAny errors TypeScript LoC TypeScript LoC Potential noImplicitAny errors The Result
  32. 0 100 200 300 400 500 600 0 20000 40000

    60000 80000 100000 120000 140000 160000 2018/07 2018/11 2019/03 2019/07 2019/11 2020/03 2020/07 noImplicitAny errors TypeScript LoC TypeScript LoC Potential noImplicitAny errors The Result Took one year to solve nearly all errors Without any action, number of potential noImplicitAny errors kept growing
  33. 0 100 200 300 400 500 600 0 20000 40000

    60000 80000 100000 120000 140000 160000 2018/07 2018/11 2019/03 2019/07 2019/11 2020/03 2020/07 noImplicitAny errors TypeScript LoC TypeScript LoC Potential noImplicitAny errors The Result Gradual adoption Short-term attack
  34. Our Long-Term Adoption Strategy › No new noImplicitAny errors! ›

    Existing files occasionally get fixed › Disallow noImplicitAny errors in files that have diff (similar to what reviewdog does)
  35. Outcome of the New Strategy › Growth of our TypeScript

    skill (recently CI rarely fails with new noImplicitAny error) › Development schedule is not affected › Of course, safer code (the any type is super unsafe!)
  36. Review Carefully › Bad type definitions could fix noImplicitAny errors

    ! › Review to ensure we have good type definitions
  37. The Short-Term Attack › Helps succeeding noImplicitAny fixes › We

    recommend performing some short-term attack at first
  38. How to Do Short-Term Attack › Do the best on

    type definition quaility › Assign TypeScript master › Fix core modules at first
  39. Conclusion Let’s enhance type safety and developer experience by various

    means!
  40. Conclusion › typescript-eslint: Enhance type safety with additional checks! ›

    noImplicitAny: Improve code quality by gradually adopting noImplicitAny! › XLT: Generate code for better type safety & DX!