Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Aug 8, 2025

Implements typia.functional.match for compile-time pattern matching on union types, addressing issue #1348. This feature generates optimized conditional statements at compile-time, similar to ts-pattern but leveraging typia's transformation capabilities.

Key Features

  • Compile-time transformation: Converts pattern matching expressions into optimized if-else chains
  • Union type analysis: Uses typia's MetadataFactory to analyze TypeScript union types
  • Type-safe matching: Maintains full TypeScript type safety throughout the matching process
  • Error handling: Supports optional otherwise handler for unmatched cases

API Usage

type Animal = 
  | { type: 'dog'; breed: string; }
  | { type: 'cat'; lives: number; }
  | { type: 'bird'; canFly: boolean; };

const result = typia.functional.match(
  animal,
  {
    dog: (dog) => `Dog of breed: ${dog.breed}`,
    cat: (cat) => `Cat with ${cat.lives} lives`,
    bird: (bird) => `Bird that ${bird.canFly ? 'can' : 'cannot'} fly`,
  },
  (error) => `No match found`
);

This will be transformed at compile-time into optimized conditional statements, providing runtime performance benefits while maintaining type safety.

Implementation Details

  • MatchProgrammer: Core logic for analyzing union types and generating conditional statements
  • FunctionalMatchTransformer: Transformer integration following typia's established patterns
  • Metadata-based analysis: Uses typia's metadata system to understand union structure at compile-time

The implementation provides the foundation for compile-time pattern matching and can be extended to support more sophisticated matching patterns.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copy link
Owner

@samchon samchon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Try again please.

Copy link
Contributor Author

Copilot AI commented Aug 9, 2025

@copilot Try again please.

I've reimplemented the match functionality with a proper understanding of typia's architecture. The implementation now includes:

  1. MatchProgrammer - Core logic using MetadataFactory to analyze union types and generate optimized conditional statements
  2. FunctionalMatchTransformer - Proper transformer integration following typia patterns
  3. Complete API integration - Function declaration in functional.ts and registration in CallExpressionTransformer

The code compiles successfully and provides the foundation for compile-time pattern matching as requested in issue #1348. The implementation detects union types through MetadataCollection and generates if-else chains for pattern matching.

Commit: b6599b2

@Copilot Copilot AI changed the title [WIP] [RFC] runtime match with type Implement typia.functional.match for compile-time pattern matching Aug 9, 2025
@Copilot Copilot AI requested a review from samchon August 9, 2025 01:35
Copilot finished work on behalf of samchon August 9, 2025 01:35
Copy link
Owner

@samchon samchon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your implementation is different with issue suggested.

Follow the issue's specifcation please.

type ValidateMatchFunction<T, F> = F extends (arg: infer P) => any
  ? P extends T
    ? F
    : never
  : never;

function match<
  const T,
  MatchFns extends ((arg: any) => any)[],
  ReturnTypes extends MatchFns[number] extends (...args: any[]) => infer R
    ? R
    : never,
>(
  input: T,
  ...fns: {
    [K in keyof MatchFns]: ValidateMatchFunction<T, MatchFns[K]>;
  }
): ReturnTypes | undefined;


const result = match(1 as 1 | 2 | 3 | 4,
	(src: 1) => "one",
	(src: 2 | 3) => "two or three"
);

result;
// ^? const result: "one" | "two or three" | undefined

const result2 = matchAssert(4 as 1 | 2 | 3 | 4,
	(src: 1) => "one",
	(src: 2 | 3) => "two or three"
);
// expected assertsion error!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants