or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdpattern-matching.mdpatterns.mdvalidation.md

pattern-matching.mddocs/

0

# Pattern Matching

1

2

Core pattern matching functionality for creating exhaustive conditional logic with type safety and smart type inference.

3

4

## Capabilities

5

6

### Match Expression

7

8

Creates a chainable pattern matching expression for handling complex conditional logic.

9

10

```typescript { .api }

11

/**

12

* Creates a pattern matching expression

13

* @param value - Input value to match against patterns

14

* @returns Match expression for chaining patterns

15

*/

16

function match<const input, output = unknown>(

17

value: input

18

): Match<input, output>;

19

```

20

21

**Usage Examples:**

22

23

```typescript

24

import { match, P } from "ts-pattern";

25

26

// Basic pattern matching

27

const result = match(value)

28

.with('hello', () => 'greeting')

29

.with('goodbye', () => 'farewell')

30

.otherwise(() => 'unknown');

31

32

// Object pattern matching

33

const response = match(apiResponse)

34

.with({ status: 'success', data: P.select() }, (data) => data)

35

.with({ status: 'error', message: P.select() }, (msg) => { throw new Error(msg) })

36

.exhaustive();

37

```

38

39

### Pattern Matching Methods

40

41

Methods available on the match expression for building pattern matching logic.

42

43

```typescript { .api }

44

interface Match<input, output> {

45

/**

46

* Match against a pattern with handler function

47

* @param pattern - Pattern to match against input

48

* @param handler - Function to execute on match

49

* @returns Updated match expression

50

*/

51

with<const pattern extends Pattern<input>>(

52

pattern: pattern,

53

handler: (selections: P.infer<pattern>, value: input) => output

54

): Match<input, output>;

55

56

/**

57

* Match against a pattern with guard condition and handler

58

* @param pattern - Pattern to match against input

59

* @param guard - Additional condition function

60

* @param handler - Function to execute on match

61

* @returns Updated match expression

62

*/

63

with<const pattern extends Pattern<input>>(

64

pattern: pattern,

65

guard: (value: input) => unknown,

66

handler: (selections: P.infer<pattern>, value: input) => output

67

): Match<input, output>;

68

69

/**

70

* Match against multiple patterns with single handler

71

* @param patterns - Multiple patterns followed by handler function

72

* @returns Updated match expression

73

*/

74

with<const patterns extends readonly Pattern<input>[]>(

75

...args: [...patterns, (selections: any, value: input) => output]

76

): Match<input, output>;

77

78

/**

79

* Match based on predicate function

80

* @param predicate - Function returning truthy value for match

81

* @param handler - Function to execute on match

82

* @returns Updated match expression

83

*/

84

when(

85

predicate: (value: input) => unknown,

86

handler: (value: input) => output

87

): Match<input, output>;

88

89

/**

90

* Provide default case and return result

91

* @param handler - Default handler function

92

* @returns Final result of pattern matching

93

*/

94

otherwise(handler: (value: input) => output): output;

95

96

/**

97

* Ensure exhaustive matching and return result

98

* @param unexpectedValueHandler - Optional error handler for unmatched cases

99

* @returns Final result of pattern matching

100

* @throws NonExhaustiveError if no patterns match

101

*/

102

exhaustive(unexpectedValueHandler?: (value: input) => never): output;

103

104

/**

105

* Alias for exhaustive()

106

* @returns Final result of pattern matching

107

*/

108

run(): output;

109

110

/**

111

* Type-level method for return type inference

112

* @returns Match expression for type inference

113

*/

114

returnType(): Match<input, output>;

115

116

/**

117

* Type-level method for input type narrowing

118

* @returns Match expression for type narrowing

119

*/

120

narrow(): Match<input, output>;

121

}

122

```

123

124

**Usage Examples:**

125

126

```typescript

127

// Multiple patterns with single handler

128

const category = match(statusCode)

129

.with(200, 201, 202, () => 'success')

130

.with(400, 401, 403, 404, () => 'client-error')

131

.with(500, 502, 503, () => 'server-error')

132

.otherwise(() => 'unknown');

133

134

// Guard conditions

135

const processUser = match(user)

136

.with(

137

{ type: 'admin' },

138

(u) => u.permissions.includes('delete'),

139

(u) => deleteUser(u)

140

)

141

.with({ type: 'user', active: true }, (u) => processActiveUser(u))

142

.otherwise(() => 'inactive or unauthorized');

143

144

// Predicate matching

145

const handleAge = match(person)

146

.when(p => p.age >= 18, (p) => 'adult: ' + p.name)

147

.when(p => p.age >= 13, (p) => 'teen: ' + p.name)

148

.otherwise(p => 'child: ' + p.name);

149

```

150

151

### Pattern Types

152

153

Core pattern types used in matching expressions.

154

155

```typescript { .api }

156

/**

157

* Base pattern type that can match values of type T

158

*/

159

type Pattern<T> =

160

| T

161

| Matcher<any, any, any, any, any>

162

| (T extends readonly (infer U)[] ? Pattern<U>[] : never)

163

| (T extends object ? { [K in keyof T]?: Pattern<T[K]> } : never);

164

165

/**

166

* Matcher protocol interface for custom patterns

167

*/

168

interface Matcher<

169

input,

170

pattern,

171

narrowedOrFn,

172

exclude = never,

173

matcherType = string

174

> {

175

[matcher](): {

176

match: (value: input) => { matched: boolean; selections?: Record<string, unknown> };

177

getSelectionKeys?: () => string[];

178

matcherType?: matcherType;

179

};

180

}

181

182

/**

183

* Symbol used for matcher protocol

184

*/

185

declare const matcher: unique symbol;

186

```

187

188

### Selection and Type Inference

189

190

Pattern matching supports value selection and provides smart type inference.

191

192

```typescript { .api }

193

/**

194

* Infer the type of value matched by a pattern

195

*/

196

type infer<pattern> = InvertPattern<NoInfer<pattern>, unknown>;

197

198

/**

199

* Narrow input type to pattern-compatible subset

200

*/

201

type narrow<input, pattern> = ExtractPreciseValue<

202

input,

203

InvertPattern<pattern, input>

204

>;

205

```

206

207

**Usage Examples:**

208

209

```typescript

210

// Type inference with selections

211

const extractData = match(response)

212

.with({ success: true, data: P.select() }, (data) => {

213

// data is properly typed based on the pattern

214

return data;

215

})

216

.with({ success: false, error: P.select() }, (error) => {

217

// error is properly typed

218

throw error;

219

})

220

.exhaustive();

221

222

// Named selections

223

const processEvent = match(event)

224

.with(

225

{ type: 'user', action: 'login', userId: P.select('id'), timestamp: P.select('time') },

226

({ id, time }) => logUserLogin(id, time)

227

)

228

.with(

229

{ type: 'system', level: 'error', message: P.select() },

230

(message) => handleSystemError(message)

231

)

232

.exhaustive();

233

```