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

Type safety initiatives for LINE Securities front-end

Type safety initiatives for LINE Securities front-end

LINE DevDay 2020

November 26, 2020
Tweet

More Decks by LINE DevDay 2020

Other Decks in Technology

Transcript

  1. View Slide

  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/

    View Slide

  3. View Slide

  4. Development of LINE Securities
    › TypeScript + React
    › 150,000+ LoC of TypeScript
    › 10+ front-end engineers working on the same project

    View Slide

  5. Our MUSTs and Type Safety
    We MUST keep
    the service up
    We MUST
    develop fast
    We MUST write
    sustainable code

    View Slide

  6. Our MUSTs and Type Safety
    Types help
    reduce bugs
    Types accelerate
    our development
    Types contribute
    to code design

    View Slide

  7. Agenda › XLT: Types for i18n Utils
    › A Custom typescript-eslint Rule
    › Gradual adoption of noImplicitAny

    View Slide

  8. XLT: Types for i18n Utils

    View Slide

  9. What is XLT?
    › In-house i18n system
    › Admin for text management and API for exporting text
    › XLT = Cross-Language Translation Tool

    View Slide

  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)

    View Slide

  11. Our Use of XLT
    › Query text with xlt function
    › Supports partial application!

    View Slide

  12. Type Safety & DX of XLT
    › Of course, fully type-safe!
    › Auto completion is there too!

    View Slide

  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? !

    View Slide

  14. Code Generation is Automated!

    View Slide

  15. Bonus: Splitting Runtime Data with Babel

    View Slide

  16. A Custom typescript-eslint Rule

    View Slide

  17. Background: A Common Pattern with JSX
    › The {cond && }
    pattern
    › Show if cond
    › Show nothing if not cond
    (React does not render false)
    › Simpler than cond ? … : null

    View Slide

  18. Actual Code with Bug
    › noticeTotal is a number | undefined
    › What if noticeTotal is 0?

    View Slide

  19. Actual Code with Bug

    View Slide

  20. Actual Code with Bug

    View Slide

  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

    View Slide

  22. Our Solution: Custom typescript-eslint Rule
    @linecorp/jsx-no-number-andand (sorry, not OSS!)

    View Slide

  23. Making a typescript-eslint Rule
    › Get a TypeChecker instance from
    custom parser
    › This provides us type information
    of expressions

    View Slide

  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

    View Slide

  25. Gradual Adoption of
    noImplicitAny

    View Slide

  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! !

    View Slide

  27. Let’s Enable noImplicitAny
    › Advice from me: always enable
    noImplicitAny when you start
    a new project
    › tsc --init already does so!

    View Slide

  28. The any Nightmare
    › The any type propagates !
    › Disaster to type safety
    › The any type disables nearly all compile errors ☠

    View Slide

  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 !

    View Slide

  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 !

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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)

    View Slide

  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!)

    View Slide

  36. Review Carefully
    › Bad type definitions could fix
    noImplicitAny errors !
    › Review to ensure we have
    good type definitions

    View Slide

  37. The Short-Term Attack
    › Helps succeeding noImplicitAny fixes
    › We recommend performing some short-term attack at first

    View Slide

  38. How to Do Short-Term Attack
    › Do the best on type definition quaility
    › Assign TypeScript master
    › Fix core modules at first

    View Slide

  39. Conclusion
    Let’s enhance type safety and
    developer experience by various means!

    View Slide

  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!

    View Slide