SlideShare a Scribd company logo
© 2024 Bloomberg Finance L.P. All rights reserved.
Enhancing Your React with
Advanced TypeScript
React + fwdays’ 24
October 19, 2024
Titian Cernicova-Dragomir
Software Engineer, TypeScript/JavaScript Infrastructure
TypeScript compiler contributor
What we will talk about today
• Should you use advanced types?
• Discriminated unions
• Mapped types
• Final thoughts
Should you use advanced types at all?
Don’t trust influencers…
• With simple views
• Things are always more complicated and nuanced
• Experts usually answer with: “It depends.”
o Unfortunately, that is not usually favored by the almighty algorithm
So, should I use complicated types?
• Depends what you mean by complicated types
• When you start out, everything is complicated
• Make sure you have enough experience with types
• Make sure the pattern you are using:
o Is well-documented
Discriminated unions
• Unions are a staple of TypeScript programming
• What makes a union discriminated?
o It has a field that uniquely selects a union constituent
o The field should usually be of a literal type
Demo: Discriminated unions as
parameters
Discriminated unions
• Unions are a staple of TypeScript programming
• What makes a union discriminated ?
o It has a field that uniquely selects a union constituent
o The field should usually be of a literal type
• Both objects and tuples can be discriminated
Demo: Tuple discriminated union
So, should I use complicated types?
• Depends what you mean by complicated types
• When you start out, everything is complicated
• Make sure the pattern you are using:
o Is well-documented
o Is worth the extra complexity
 Usually, a case where we can improve the call site DX
 The code is going to be reused a lot
Generics – Introduction
• A function can have type parameters
• We can use the type parameter as a type anywhere in the function
• Type parameters can capture information from the call site
• We can use type parameters to tie together:
• Some parameters types to other parameter types
• Some parameters types to the return type
function getValue<T>() { }
function getValue<T>(p: T) { }
getValue(10) // T = number
function getValue<T>(p: T | undefined, defaultValue:
T) { }
let value: number | undefined;
getValue(value, 10) // p: number |
undefined,defaultValue: T
getValue(value,"1") // Error
function getValue<T>(p: T | undefined, defaultValue:
T): T
let value: number | undefined;
getValue(value, 10) // Returns number
Demo: Generic Dialog Hook
So, should I use complicated types?
• Depends what you mean by complicated types
• When you start out, everything is complicated
• Make sure you have enough experience with types
• Make sure the pattern you are using:
o Is well-documented
o Is worth the extra complexity
o Can be understood by others
Make sure the pattern you are using can be understood by others
• Complicated conditional and mapped types are:
o Often hard to understand
 Even for the person that wrote them
Make sure the pattern you are using can be understood by others
type PrimitiveSchemaToType<T extends PrimitiveSchemaDefinition> = PrimitiveTypeNameToType[T['type']];
type SchemaDefinition = PrimitiveSchemaDefinition | ObjectSchemaDefinition | EnumSchemaDefinition<any>
| ArraySchemaDefinition<any> | UnionSchemaDefinition<any>
type SchemaToType<T extends SchemaDefinition> =
T extends PrimitiveSchemaDefinition? PrimitiveSchemaToType<T> :
T extends ObjectSchemaDefinition? ObjectSchemaToType<T> :
T extends EnumSchemaDefinition<infer U> ? U :
T extends ArraySchemaDefinition<infer U> ? SchemaToType<U>[] :
T extends UnionSchemaDefinition<infer U>? SchemaToType<U>:
never;
type ObjectSchemaToTypeOptionalPart<T extends ObjectSchemaDefinition> = {
-readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? P: never]?:
SchemaToType<T['fields'][P]>
}
type ObjectSchemaToTypeRequiredPart<T extends ObjectSchemaDefinition> = {
-readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? never: P]:
SchemaToType<T['fields'][P]>
}
😃
Make sure the pattern you are using can be understood by others
type PrimitiveSchemaToType<T extends PrimitiveSchemaDefinition> = PrimitiveTypeNameToType[T['type']];
type SchemaDefinition = PrimitiveSchemaDefinition | ObjectSchemaDefinition | EnumSchemaDefinition<any>
| ArraySchemaDefinition<any> | UnionSchemaDefinition<any>
type SchemaToType<T extends SchemaDefinition> =
T extends PrimitiveSchemaDefinition? PrimitiveSchemaToType<T> :
T extends ObjectSchemaDefinition? ObjectSchemaToType<T> :
T extends EnumSchemaDefinition<infer U> ? U :
T extends ArraySchemaDefinition<infer U> ? SchemaToType<U>[] :
T extends UnionSchemaDefinition<infer U>? SchemaToType<U>:
never;
type ObjectSchemaToTypeOptionalPart<T extends ObjectSchemaDefinition> = {
-readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? P: never]?:
SchemaToType<T['fields'][P]>
}
type ObjectSchemaToTypeRequiredPart<T extends ObjectSchemaDefinition> = {
-readonly [P in keyof T['fds'] as T['fields'][P] extends { required: false }? never:
P]:
SchemaToType<T['fields'][P]>
}
😕
😕
😕
😕
😕
😕
Make sure the pattern you are using can be understood by others
• Complicated nested conditional and mapped types are:
o Often hard to understand
o Hard to debug
 No built-in debugger
 Split and hover debugging only 😞
Make sure the pattern you are using can be understood by others
• Complicated nested conditional and mapped types are:
o Often hard to understand
o Hard to debug
• Prefer built-in mapped and conditional types whenever possible
• Change modifiers: Partial<T>, Readonly<T>, Required<T>
• Manipulate properties: Pick<T>, Omit<T>, Record<T, K>
• Extract types: Parameters<T>, ReturnType<T>, InstanceType<T>
Anatomy of a mapped type
• Iterate over a union of keys
• Often paired with keyof – To get the keys of an existing object type
• We can change the type of each property
• We often index into the original type to the type of the original property
Demo: Form with validation
Demo – Form with validation
• Was that example overly complicated?
o Not if you know the syntax
• The problems usually come when we layer:
o Mapped types on top of other complex types
o Conditional types on top of other complex types
• What kind of problems?
o Readability and maintainability
o Compiler performance
o IDE performance
You probably shouldn’t
• Obsess about generic function implementation type safety
o Complex types generally require some type assertions
o You are optimizing for caller DX
• Use complex types for single use code
o Not worth the cost
You probably shouldn’t – Xtreme edition
• Create your own class system
o ES already has classes
o If you already have it as a legacy
 You might benefit from some advanced types to help you migrate
 Work on migrating
• Parsing other languages in the type system
o Will probably make your complier slow
o Will probably generate hard to read errors
• Anything that takes advantage of the fact that the TypeScript type system is
Turing-complete
You probably should
• Get familiar with more advanced TypeScript techniques
o Even if you don’t write them, you will still benefit from understanding them
• Use conditional/mapped types in library code
o To improve DX for your users.
• Make sure your team also can understand and maintain your advanced
TypeScript types
© 2024 Bloomberg Finance L.P. All rights reserved.
Thank you for listening!
Questions?
@TitianCernicova

More Related Content

PDF
Introduction to typescript
PPTX
Type Driven Development with TypeScript
PDF
TypeScript Introduction
PPTX
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
PPTX
Typescript: Beginner to Advanced
PDF
Introduction to TypeScript
PDF
Typescript is the best by Maxim Kryuk
PDF
Typescript is the best
Introduction to typescript
Type Driven Development with TypeScript
TypeScript Introduction
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
Typescript: Beginner to Advanced
Introduction to TypeScript
Typescript is the best by Maxim Kryuk
Typescript is the best

Similar to "Enhancing Your React with Advanced TypeScript", Titian Cernicova-Dragomir (20)

PPTX
TypeScript by Howard
PPTX
Howard type script
PPTX
Type script by Howard
PPTX
Introduction to TypeScript
PPTX
Type script is awesome
PDF
Strongly typed web applications by Adel Salakh
PDF
Flow or Type - how to React to that?
PPTX
Introduction to TypeScript
PDF
Антихрупкий TypeScript | Odessa Frontend Meetup #17
PDF
Types For Frontend Developers
PDF
Static types on javascript?! Type checking approaches to ensure healthy appli...
PDF
A la découverte de TypeScript
PPTX
A Details Overview How to Use Typescript Generic Type
PPTX
Dependent Types make bad data unrepresentable
PPTX
Type script
PDF
Practical TypeScript
PPTX
Type script - advanced usage and practices
PDF
Ask The Expert - Typescript: A stitch in time saves nine
PDF
TypeScript Interview Questions PDF By ScholarHat
PPTX
Complete Notes on Angular 2 and TypeScript
TypeScript by Howard
Howard type script
Type script by Howard
Introduction to TypeScript
Type script is awesome
Strongly typed web applications by Adel Salakh
Flow or Type - how to React to that?
Introduction to TypeScript
Антихрупкий TypeScript | Odessa Frontend Meetup #17
Types For Frontend Developers
Static types on javascript?! Type checking approaches to ensure healthy appli...
A la découverte de TypeScript
A Details Overview How to Use Typescript Generic Type
Dependent Types make bad data unrepresentable
Type script
Practical TypeScript
Type script - advanced usage and practices
Ask The Expert - Typescript: A stitch in time saves nine
TypeScript Interview Questions PDF By ScholarHat
Complete Notes on Angular 2 and TypeScript
Ad

More from Fwdays (20)

PDF
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
PDF
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
PPTX
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
PPTX
"Як ми переписали Сільпо на Angular", Євген Русаков
PDF
"AI Transformation: Directions and Challenges", Pavlo Shaternik
PDF
"Validation and Observability of AI Agents", Oleksandr Denisyuk
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
PPTX
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
PPTX
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
PDF
"AI is already here. What will happen to your team (and your role) tomorrow?"...
PPTX
"Is it worth investing in AI in 2025?", Alexander Sharko
PDF
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
PDF
"Scaling in space and time with Temporal", Andriy Lupa.pdf
PDF
"Database isolation: how we deal with hundreds of direct connections to the d...
PDF
"Scaling in space and time with Temporal", Andriy Lupa .pdf
PPTX
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
PPTX
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
PPTX
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
PPTX
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
"Mastering UI Complexity: State Machines and Reactive Patterns at Grammarly",...
"Effect, Fiber & Schema: tactical and technical characteristics of Effect.ts"...
"Computer Use Agents: From SFT to Classic RL", Maksym Shamrai
"Як ми переписали Сільпо на Angular", Євген Русаков
"AI Transformation: Directions and Challenges", Pavlo Shaternik
"Validation and Observability of AI Agents", Oleksandr Denisyuk
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
"Co-Authoring with a Machine: What I Learned from Writing a Book on Generativ...
"Human-AI Collaboration Models for Better Decisions, Faster Workflows, and Cr...
"AI is already here. What will happen to your team (and your role) tomorrow?"...
"Is it worth investing in AI in 2025?", Alexander Sharko
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Database isolation: how we deal with hundreds of direct connections to the d...
"Scaling in space and time with Temporal", Andriy Lupa .pdf
"Provisioning via DOT-Chain: from catering to drone marketplaces", Volodymyr ...
" Observability with Elasticsearch: Best Practices for High-Load Platform", A...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"Istio Ambient Mesh in production: our way from Sidecar to Sidecar-less",Hlib...
Ad

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
cuic standard and advanced reporting.pdf
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Cloud computing and distributed systems.
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Spectroscopy.pptx food analysis technology
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Electronic commerce courselecture one. Pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
Teaching material agriculture food technology
Reach Out and Touch Someone: Haptics and Empathic Computing
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
cuic standard and advanced reporting.pdf
A comparative analysis of optical character recognition models for extracting...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Cloud computing and distributed systems.
Chapter 3 Spatial Domain Image Processing.pdf
Assigned Numbers - 2025 - Bluetooth® Document
“AI and Expert System Decision Support & Business Intelligence Systems”
MYSQL Presentation for SQL database connectivity
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Spectroscopy.pptx food analysis technology
Spectral efficient network and resource selection model in 5G networks
MIND Revenue Release Quarter 2 2025 Press Release
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Electronic commerce courselecture one. Pdf
Programs and apps: productivity, graphics, security and other tools

"Enhancing Your React with Advanced TypeScript", Titian Cernicova-Dragomir

  • 1. © 2024 Bloomberg Finance L.P. All rights reserved. Enhancing Your React with Advanced TypeScript React + fwdays’ 24 October 19, 2024 Titian Cernicova-Dragomir Software Engineer, TypeScript/JavaScript Infrastructure TypeScript compiler contributor
  • 2. What we will talk about today • Should you use advanced types? • Discriminated unions • Mapped types • Final thoughts
  • 3. Should you use advanced types at all?
  • 4. Don’t trust influencers… • With simple views • Things are always more complicated and nuanced • Experts usually answer with: “It depends.” o Unfortunately, that is not usually favored by the almighty algorithm
  • 5. So, should I use complicated types? • Depends what you mean by complicated types • When you start out, everything is complicated • Make sure you have enough experience with types • Make sure the pattern you are using: o Is well-documented
  • 6. Discriminated unions • Unions are a staple of TypeScript programming • What makes a union discriminated? o It has a field that uniquely selects a union constituent o The field should usually be of a literal type
  • 8. Discriminated unions • Unions are a staple of TypeScript programming • What makes a union discriminated ? o It has a field that uniquely selects a union constituent o The field should usually be of a literal type • Both objects and tuples can be discriminated
  • 10. So, should I use complicated types? • Depends what you mean by complicated types • When you start out, everything is complicated • Make sure the pattern you are using: o Is well-documented o Is worth the extra complexity  Usually, a case where we can improve the call site DX  The code is going to be reused a lot
  • 11. Generics – Introduction • A function can have type parameters • We can use the type parameter as a type anywhere in the function • Type parameters can capture information from the call site • We can use type parameters to tie together: • Some parameters types to other parameter types • Some parameters types to the return type function getValue<T>() { } function getValue<T>(p: T) { } getValue(10) // T = number function getValue<T>(p: T | undefined, defaultValue: T) { } let value: number | undefined; getValue(value, 10) // p: number | undefined,defaultValue: T getValue(value,"1") // Error function getValue<T>(p: T | undefined, defaultValue: T): T let value: number | undefined; getValue(value, 10) // Returns number
  • 13. So, should I use complicated types? • Depends what you mean by complicated types • When you start out, everything is complicated • Make sure you have enough experience with types • Make sure the pattern you are using: o Is well-documented o Is worth the extra complexity o Can be understood by others
  • 14. Make sure the pattern you are using can be understood by others • Complicated conditional and mapped types are: o Often hard to understand  Even for the person that wrote them
  • 15. Make sure the pattern you are using can be understood by others type PrimitiveSchemaToType<T extends PrimitiveSchemaDefinition> = PrimitiveTypeNameToType[T['type']]; type SchemaDefinition = PrimitiveSchemaDefinition | ObjectSchemaDefinition | EnumSchemaDefinition<any> | ArraySchemaDefinition<any> | UnionSchemaDefinition<any> type SchemaToType<T extends SchemaDefinition> = T extends PrimitiveSchemaDefinition? PrimitiveSchemaToType<T> : T extends ObjectSchemaDefinition? ObjectSchemaToType<T> : T extends EnumSchemaDefinition<infer U> ? U : T extends ArraySchemaDefinition<infer U> ? SchemaToType<U>[] : T extends UnionSchemaDefinition<infer U>? SchemaToType<U>: never; type ObjectSchemaToTypeOptionalPart<T extends ObjectSchemaDefinition> = { -readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? P: never]?: SchemaToType<T['fields'][P]> } type ObjectSchemaToTypeRequiredPart<T extends ObjectSchemaDefinition> = { -readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? never: P]: SchemaToType<T['fields'][P]> } 😃
  • 16. Make sure the pattern you are using can be understood by others type PrimitiveSchemaToType<T extends PrimitiveSchemaDefinition> = PrimitiveTypeNameToType[T['type']]; type SchemaDefinition = PrimitiveSchemaDefinition | ObjectSchemaDefinition | EnumSchemaDefinition<any> | ArraySchemaDefinition<any> | UnionSchemaDefinition<any> type SchemaToType<T extends SchemaDefinition> = T extends PrimitiveSchemaDefinition? PrimitiveSchemaToType<T> : T extends ObjectSchemaDefinition? ObjectSchemaToType<T> : T extends EnumSchemaDefinition<infer U> ? U : T extends ArraySchemaDefinition<infer U> ? SchemaToType<U>[] : T extends UnionSchemaDefinition<infer U>? SchemaToType<U>: never; type ObjectSchemaToTypeOptionalPart<T extends ObjectSchemaDefinition> = { -readonly [P in keyof T['fields'] as T['fields'][P] extends { required: false }? P: never]?: SchemaToType<T['fields'][P]> } type ObjectSchemaToTypeRequiredPart<T extends ObjectSchemaDefinition> = { -readonly [P in keyof T['fds'] as T['fields'][P] extends { required: false }? never: P]: SchemaToType<T['fields'][P]> } 😕 😕 😕 😕 😕 😕
  • 17. Make sure the pattern you are using can be understood by others • Complicated nested conditional and mapped types are: o Often hard to understand o Hard to debug  No built-in debugger  Split and hover debugging only 😞
  • 18. Make sure the pattern you are using can be understood by others • Complicated nested conditional and mapped types are: o Often hard to understand o Hard to debug • Prefer built-in mapped and conditional types whenever possible • Change modifiers: Partial<T>, Readonly<T>, Required<T> • Manipulate properties: Pick<T>, Omit<T>, Record<T, K> • Extract types: Parameters<T>, ReturnType<T>, InstanceType<T>
  • 19. Anatomy of a mapped type • Iterate over a union of keys • Often paired with keyof – To get the keys of an existing object type • We can change the type of each property • We often index into the original type to the type of the original property
  • 20. Demo: Form with validation
  • 21. Demo – Form with validation • Was that example overly complicated? o Not if you know the syntax • The problems usually come when we layer: o Mapped types on top of other complex types o Conditional types on top of other complex types • What kind of problems? o Readability and maintainability o Compiler performance o IDE performance
  • 22. You probably shouldn’t • Obsess about generic function implementation type safety o Complex types generally require some type assertions o You are optimizing for caller DX • Use complex types for single use code o Not worth the cost
  • 23. You probably shouldn’t – Xtreme edition • Create your own class system o ES already has classes o If you already have it as a legacy  You might benefit from some advanced types to help you migrate  Work on migrating • Parsing other languages in the type system o Will probably make your complier slow o Will probably generate hard to read errors • Anything that takes advantage of the fact that the TypeScript type system is Turing-complete
  • 24. You probably should • Get familiar with more advanced TypeScript techniques o Even if you don’t write them, you will still benefit from understanding them • Use conditional/mapped types in library code o To improve DX for your users. • Make sure your team also can understand and maintain your advanced TypeScript types
  • 25. © 2024 Bloomberg Finance L.P. All rights reserved. Thank you for listening! Questions? @TitianCernicova