or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-tuple-types.mdbasic-types.mdchange-case-types.mddeep-wrapper-types.mdfunction-types.mdindex.mdkey-types.mdmark-wrapper-types.mdtype-checkers.mdutility-functions.mdutility-types.md

type-checkers.mddocs/

0

# Type Checkers

1

2

Conditional types for runtime type validation and compile-time type detection. These utilities help you validate and work with type characteristics at both compile time and runtime.

3

4

## Capabilities

5

6

### Exact

7

8

Returns `Type` when type `Type` and `Shape` are identical. Otherwise returns `never`.

9

10

```typescript { .api }

11

type Exact<Type, Shape> = [Type] extends [Shape]

12

? [Shape] extends [Type]

13

? Type

14

: never

15

: never;

16

```

17

18

**Usage Example:**

19

20

```typescript

21

import type { Exact } from "ts-essentials";

22

23

type User = { id: number; name: string; };

24

type UserShape = { id: number; name: string; };

25

type ExtendedUser = { id: number; name: string; email: string; };

26

27

type ExactUser = Exact<User, UserShape>; // User (exact match)

28

type NotExactUser = Exact<User, ExtendedUser>; // never (not exact)

29

30

// Useful for ensuring exact type matches in generics

31

function processExactType<T, U>(

32

value: T,

33

shape: Exact<T, U>

34

): T {

35

return value;

36

}

37

```

38

39

### IsAny

40

41

Returns `true` when type `Type` is `any`. Otherwise returns `false`.

42

43

```typescript { .api }

44

type IsAny<Type> = 0 extends 1 & Type ? true : false;

45

```

46

47

**Usage Example:**

48

49

```typescript

50

import type { IsAny } from "ts-essentials";

51

52

type CheckAny1 = IsAny<any>; // true

53

type CheckAny2 = IsAny<unknown>; // false

54

type CheckAny3 = IsAny<string>; // false

55

type CheckAny4 = IsAny<never>; // false

56

57

// Useful for conditional type logic

58

type SafeType<T> = IsAny<T> extends true ? unknown : T;

59

60

// Runtime usage in type guards

61

function isAnyType<T>(value: T): value is IsAny<T> extends true ? any : never {

62

// Implementation for checking if a value came from an 'any' type

63

return false; // This is conceptual - 'any' detection is compile-time only

64

}

65

```

66

67

### IsNever

68

69

Returns `true` when type `Type` is `never`. Otherwise returns `false`.

70

71

```typescript { .api }

72

type IsNever<Type> = [Type] extends [never] ? true : false;

73

```

74

75

**Usage Example:**

76

77

```typescript

78

import type { IsNever } from "ts-essentials";

79

80

type CheckNever1 = IsNever<never>; // true

81

type CheckNever2 = IsNever<any>; // false

82

type CheckNever3 = IsNever<unknown>; // false

83

type CheckNever4 = IsNever<string>; // false

84

85

// Useful for filtering out never types

86

type FilterNever<T> = IsNever<T> extends true ? never : T;

87

88

type Union = string | never | number;

89

type Filtered = FilterNever<Union>; // string | number

90

91

// Conditional logic based on never detection

92

type ProcessType<T> = IsNever<T> extends true

93

? "No valid type"

94

: `Processing: ${T extends string ? T : "unknown"}`;

95

```

96

97

### IsUnknown

98

99

Returns `true` when type `Type` is `unknown`. Otherwise returns `false`.

100

101

```typescript { .api }

102

type IsUnknown<Type> = [unknown] extends [Type]

103

? [Type] extends [unknown]

104

? true

105

: false

106

: false;

107

```

108

109

**Usage Example:**

110

111

```typescript

112

import type { IsUnknown } from "ts-essentials";

113

114

type CheckUnknown1 = IsUnknown<unknown>; // true

115

type CheckUnknown2 = IsUnknown<any>; // false

116

type CheckUnknown3 = IsUnknown<string>; // false

117

type CheckUnknown4 = IsUnknown<never>; // false

118

119

// Useful for providing safer defaults

120

type SafeDefault<T> = IsUnknown<T> extends true ? string : T;

121

122

type Example1 = SafeDefault<unknown>; // string

123

type Example2 = SafeDefault<number>; // number

124

125

// Type-safe unknown handling

126

type HandleUnknown<T> = IsUnknown<T> extends true

127

? "Please provide a more specific type"

128

: T;

129

```

130

131

### IsTuple

132

133

Returns `Type` when type `Type` is tuple. Otherwise returns `never`.

134

135

```typescript { .api }

136

type IsTuple<Type> = Type extends ReadonlyArray<any>

137

? number extends Type['length']

138

? never

139

: Type

140

: never;

141

```

142

143

**Usage Example:**

144

145

```typescript

146

import type { IsTuple } from "ts-essentials";

147

148

type CheckTuple1 = IsTuple<[string, number]>; // [string, number]

149

type CheckTuple2 = IsTuple<readonly [string, number]>; // readonly [string, number]

150

type CheckTuple3 = IsTuple<string[]>; // never

151

type CheckTuple4 = IsTuple<Array<string>>; // never

152

153

// Process only tuple types

154

type ProcessTuple<T> = IsTuple<T> extends never

155

? "Not a tuple"

156

: T;

157

158

type Result1 = ProcessTuple<[1, 2, 3]>; // [1, 2, 3]

159

type Result2 = ProcessTuple<number[]>; // "Not a tuple"

160

161

// Tuple-specific operations

162

type TupleLength<T> = IsTuple<T> extends never ? never : T['length'];

163

type Len1 = TupleLength<[1, 2, 3]>; // 3

164

type Len2 = TupleLength<string[]>; // never

165

```

166

167

### NonEmptyObject

168

169

Returns `Object` when `Object` has at least one key. Otherwise returns `never`.

170

171

```typescript { .api }

172

type NonEmptyObject<Object extends AnyRecord> = keyof Object extends never ? never : Object;

173

```

174

175

**Usage Example:**

176

177

```typescript

178

import type { NonEmptyObject } from "ts-essentials";

179

180

type CheckObject1 = NonEmptyObject<{ id: number; name: string; }>; // { id: number; name: string; }

181

type CheckObject2 = NonEmptyObject<{}>; // never

182

type CheckObject3 = NonEmptyObject<Record<string, never>>; // never

183

184

// Ensure objects have properties

185

function processNonEmptyObject<T extends Record<string, any>>(

186

obj: NonEmptyObject<T>

187

): NonEmptyObject<T> {

188

return obj;

189

}

190

191

// This works

192

processNonEmptyObject({ id: 1, name: "test" });

193

194

// This would cause a compile error:

195

// processNonEmptyObject({}); // Error: Argument of type '{}' is not assignable

196

197

// Conditional processing based on object emptiness

198

type ProcessObject<T> = NonEmptyObject<T> extends never

199

? "Empty object"

200

: keyof T;

201

202

type Result1 = ProcessObject<{ a: 1; b: 2; }>; // "a" | "b"

203

type Result2 = ProcessObject<{}>; // "Empty object"

204

```

205

206

## Advanced Usage

207

208

Combine type checkers for complex type validation:

209

210

```typescript

211

import type { IsAny, IsNever, IsUnknown, IsTuple, NonEmptyObject } from "ts-essentials";

212

213

// Complex type validation

214

type ValidateType<T> =

215

IsAny<T> extends true ? "Invalid: any type"

216

: IsNever<T> extends true ? "Invalid: never type"

217

: IsUnknown<T> extends true ? "Invalid: unknown type"

218

: T extends object

219

? NonEmptyObject<T> extends never

220

? "Invalid: empty object"

221

: "Valid object type"

222

: T extends ReadonlyArray<any>

223

? IsTuple<T> extends never

224

? "Valid array type"

225

: "Valid tuple type"

226

: "Valid primitive type";

227

228

type Test1 = ValidateType<{ id: number; }>; // "Valid object type"

229

type Test2 = ValidateType<[]>; // "Valid tuple type"

230

type Test3 = ValidateType<string[]>; // "Valid array type"

231

type Test4 = ValidateType<{}>; // "Invalid: empty object"

232

type Test5 = ValidateType<any>; // "Invalid: any type"

233

```

234

235

## Types

236

237

```typescript { .api }

238

type AnyRecord<T = any> = Record<KeyofBase, T>;

239

type KeyofBase = string | number | symbol;

240

```