TSConf 2020: TypeScript Innovation in a Virtual World
Table of Contents
TSConf 2020 | Virtual Conference
TSConf 2020 was held virtually on October 9, 2020, adapting to the global pandemic while continuing to bring the TypeScript community together.
Presentation
Template Literal Types
// TypeScript 4.1 Template Literal Types
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type APIEndpoint = `/api/${string}`;
type APIRoute = `${HTTPMethod} ${APIEndpoint}`;
const route: APIRoute = "GET /api/users"; // Valid
Variadic Tuple Types
// TypeScript 4.0 Variadic Tuple Types
type Concat<T extends unknown[], U extends unknown[]> = [...T, ...U];
type Result = Concat<[1, 2], [3, 4]>; // [1, 2, 3, 4]
function concat<T extends unknown[], U extends unknown[]>(
arr1: T, arr2: U
): Concat<T, U> {
return [...arr1, ...arr2] as Concat<T, U>;
}
Sessions
TypeScript 4.0 and Beyond
// Labeled Tuple Elements
type Address = [streetNumber: number, street: string, city: string];
// Class Property Inference from Constructors
class Point {
x: number;
y: number;
constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
}
Monorepos and Project References
// tsconfig.json for project references
{
"compilerOptions": {
"composite": true,
"declaration": true,
"declarationMap": true
},
"references": [
{ "path": "../shared" },
{ "path": "../utils" }
]
}
React and TypeScript Best Practices
// Modern React with TypeScript
import React, { FC, useState } from 'react';
interface Props {
initialCount: number;
}
const Counter: FC<Props> = ({ initialCount }) => {
const [count, setCount] = useState(initialCount);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
</div>
);
};
Advanced Type Patterns
// Recursive Conditional Types
type Awaited<T> = T extends Promise<infer U> ? Awaited<U> : T;
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object
? DeepReadonly<T[P]>
: T[P];
};
// Example usage
type NestedPromise = Promise<Promise<string>>;
type Resolved = Awaited<NestedPromise>; // string
Error Handling Patterns
// Result type pattern for error handling
type Result<T, E = Error> =
| { ok: true; value: T }
| { ok: false; error: E };
function divide(a: number, b: number): Result<number, string> {
if (b === 0) {
return { ok: false, error: "Division by zero" };
}
return { ok: true, value: a / b };
}
const result = divide(10, 2);
if (result.ok) {
console.log(result.value); // TypeScript knows this is number
}
TypeScript in Production
// Strict configuration for production
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true
}
}
Conference Highlights
Virtual Format Success
Despite the transition to virtual format, TSConf 2020 maintained high engagement with live Q&A sessions and interactive workshops.
Community Growth
The TypeScript community continued to grow, with increased adoption in enterprise environments and the open source ecosystem.