TSConf 2021: TypeScript Maturity and Enterprise Adoption

Table of Contents

TSConf 2021 | Virtual Conference

TSConf 2021 continued the virtual format, bringing together TypeScript developers worldwide to explore the latest features and best practices.

Presentation

Control Flow Analysis Improvements

// TypeScript 4.4 Control Flow Analysis
function example(x: string | number | boolean) {
  if (typeof x === "string") {
    console.log(x.toUpperCase()); // x is string
  } else if (typeof x === "number") {
    console.log(x.toFixed(2)); // x is number
  } else {
    console.log(x); // x is boolean
  }
}

// Aliased conditions now work
function aliasedCheck(x: string | number) {
  const isString = typeof x === "string";
  if (isString) {
    console.log(x.toUpperCase()); // x is narrowed to string
  }
}

Template Literal Type Inference

// Infer within template literal types
type ExtractRouteParams<T extends string> =
  T extends `${infer _Start}:${infer Param}/${infer Rest}`
    ? Param | ExtractRouteParams<Rest>
    : T extends `${infer _Start}:${infer Param}`
    ? Param
    : never;

type Params = ExtractRouteParams<"/users/:userId/posts/:postId">;
// type Params = "userId" | "postId"

Sessions

TypeScript 4.4 and 4.5 Features

// Static Index Signatures
interface StringByString {
  [key: string]: string;
}

// Exact optional property types
interface Config {
  name: string;
  value?: string; // undefined is not assignable by default with exactOptionalPropertyTypes
}

// Awaited Type built-in
type T = Awaited<Promise<Promise<string>>>; // string

Abstract Construct Signatures

// TypeScript 4.2 Abstract Construct Signatures
abstract class Shape {
  abstract getArea(): number;
}

type Constructor<T> = abstract new (...args: any[]) => T;

function createInstance<T extends Shape>(
  Ctor: Constructor<T>,
  ...args: ConstructorParameters<typeof Ctor>
): T {
  // This allows abstract classes to be passed
  throw new Error("Cannot instantiate abstract class");
}

ES Modules in Node.js with TypeScript

// package.json
{
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  }
}

// tsconfig.json
{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true
  }
}

// Usage with .js extension required
import { helper } from "./utils.js";

Type-Safe API Design

// Branded types for type safety
type UserId = string & { readonly brand: unique symbol };
type OrderId = string & { readonly brand: unique symbol };

function createUserId(id: string): UserId {
  return id as UserId;
}

function createOrderId(id: string): OrderId {
  return id as OrderId;
}

function getUser(id: UserId): void {
  // Only accepts UserId, not OrderId or plain string
}

const userId = createUserId("user-123");
const orderId = createOrderId("order-456");

getUser(userId); // OK
// getUser(orderId); // Error: Argument of type 'OrderId' is not assignable

Testing TypeScript Applications

// Type-safe testing with vitest
import { describe, it, expect, vi } from 'vitest';

interface UserService {
  getUser(id: string): Promise<User>;
}

const mockUserService: UserService = {
  getUser: vi.fn().mockResolvedValue({ id: '1', name: 'Test User' })
};

describe('UserController', () => {
  it('should fetch user by id', async () => {
    const user = await mockUserService.getUser('1');
    expect(user.name).toBe('Test User');
  });
});

Performance and Bundle Optimization

// Tree-shaking friendly exports
// utils/index.ts
export { formatDate } from './date.js';
export { formatCurrency } from './currency.js';

// Avoid namespace exports for tree-shaking
// Instead of: export * as utils from './utils';
// Use individual exports

// Type-only imports for build optimization
import type { User } from './types.js';
import { validateUser } from './validators.js';

Conference Highlights

Enterprise TypeScript

Discussions on TypeScript adoption at scale, including migration strategies and maintaining large TypeScript codebases.

Community Tools

Showcases of community tools including tsc alternatives, linting configurations, and development workflows.

Future of TypeScript

Previews of upcoming features and the TypeScript roadmap, with input from the TypeScript team.

Author: Jason Walsh

j@wal.sh

Last Updated: 2026-01-10 17:13:21

build: 2026-01-11 18:26 | sha: 48a6da1