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

key-types.mddocs/

0

# Key Types

1

2

Extract and work with object property keys based on their characteristics (optional, required, readonly, writable). These types help you work with the structure and metadata of object types.

3

4

## Capabilities

5

6

### OptionalKeys

7

8

Constructs a union type by picking all optional properties of object type `Type`.

9

10

```typescript { .api }

11

type OptionalKeys<Type> = {

12

[K in keyof Type]-?: {} extends Pick<Type, K> ? K : never;

13

}[keyof Type];

14

```

15

16

**Usage Example:**

17

18

```typescript

19

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

20

21

type User = {

22

id: number;

23

name: string;

24

email?: string;

25

avatar?: string;

26

bio?: string;

27

};

28

29

type UserOptionalKeys = OptionalKeys<User>;

30

// Result: "email" | "avatar" | "bio"

31

32

// Use with Pick to get all optional properties

33

type OptionalUserProps = Pick<User, OptionalKeys<User>>;

34

// Result: { email?: string; avatar?: string; bio?: string; }

35

```

36

37

### PickKeys

38

39

Constructs a union type by picking all properties of object type `Type` which values are assignable to type `Value`.

40

41

```typescript { .api }

42

type PickKeys<Type, Value> = {

43

[K in keyof Type]: Type[K] extends Value ? K : never;

44

}[keyof Type];

45

```

46

47

**Usage Example:**

48

49

```typescript

50

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

51

52

type User = {

53

id: number;

54

name: string;

55

email: string;

56

age: number;

57

isActive: boolean;

58

isAdmin: boolean;

59

};

60

61

type StringKeys = PickKeys<User, string>;

62

// Result: "name" | "email"

63

64

type BooleanKeys = PickKeys<User, boolean>;

65

// Result: "isActive" | "isAdmin"

66

67

type NumberKeys = PickKeys<User, number>;

68

// Result: "id" | "age"

69

70

// Use with Pick to extract properties by type

71

type UserStrings = Pick<User, PickKeys<User, string>>;

72

// Result: { name: string; email: string; }

73

```

74

75

### ReadonlyKeys

76

77

Constructs a union type by picking all `readonly` properties of object type `Type`.

78

79

```typescript { .api }

80

type ReadonlyKeys<Type> = {

81

[K in keyof Type]-?: ReadonlyEquivalent<

82

{ [Q in K]: Type[K] },

83

{ -readonly [Q in K]: Type[K] }

84

> extends true

85

? never

86

: K;

87

}[keyof Type];

88

```

89

90

**Usage Example:**

91

92

```typescript

93

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

94

95

type User = {

96

readonly id: number;

97

name: string;

98

readonly createdAt: Date;

99

email: string;

100

readonly version: number;

101

};

102

103

type UserReadonlyKeys = ReadonlyKeys<User>;

104

// Result: "id" | "createdAt" | "version"

105

106

// Use with Pick to get all readonly properties

107

type ReadonlyUserProps = Pick<User, ReadonlyKeys<User>>;

108

// Result: { readonly id: number; readonly createdAt: Date; readonly version: number; }

109

```

110

111

### RequiredKeys

112

113

Constructs a union type by picking all required properties of object type `Type`.

114

115

```typescript { .api }

116

type RequiredKeys<Type> = {

117

[K in keyof Type]-?: {} extends Pick<Type, K> ? never : K;

118

}[keyof Type];

119

```

120

121

**Usage Example:**

122

123

```typescript

124

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

125

126

type User = {

127

id: number;

128

name: string;

129

email?: string;

130

avatar?: string;

131

createdAt: Date;

132

};

133

134

type UserRequiredKeys = RequiredKeys<User>;

135

// Result: "id" | "name" | "createdAt"

136

137

// Use with Pick to get all required properties

138

type RequiredUserProps = Pick<User, RequiredKeys<User>>;

139

// Result: { id: number; name: string; createdAt: Date; }

140

141

// Useful for validation schemas

142

function validateRequiredFields<T>(

143

obj: T,

144

requiredKeys: RequiredKeys<T>[]

145

): boolean {

146

return requiredKeys.every(key => obj[key] !== undefined);

147

}

148

```

149

150

### WritableKeys

151

152

Constructs a union type by picking all writable properties of object type `Type`, meaning their values can be reassigned.

153

154

```typescript { .api }

155

type WritableKeys<Type> = {

156

[K in keyof Type]-?: ReadonlyEquivalent<

157

{ [Q in K]: Type[K] },

158

{ -readonly [Q in K]: Type[K] }

159

> extends true

160

? K

161

: never;

162

}[keyof Type];

163

```

164

165

**Usage Example:**

166

167

```typescript

168

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

169

170

type User = {

171

readonly id: number;

172

name: string;

173

email: string;

174

readonly createdAt: Date;

175

isActive: boolean;

176

};

177

178

type UserWritableKeys = WritableKeys<User>;

179

// Result: "name" | "email" | "isActive"

180

181

// Use with Pick to get all writable properties

182

type WritableUserProps = Pick<User, WritableKeys<User>>;

183

// Result: { name: string; email: string; isActive: boolean; }

184

185

// Useful for update operations

186

function updateUser<T>(

187

user: T,

188

updates: Partial<Pick<T, WritableKeys<T>>>

189

): T {

190

return { ...user, ...updates };

191

}

192

```

193

194

## Advanced Usage

195

196

Combine multiple key type utilities for complex type operations:

197

198

```typescript

199

import type { RequiredKeys, OptionalKeys, WritableKeys, ReadonlyKeys, PickKeys } from "ts-essentials";

200

201

type User = {

202

readonly id: number;

203

name: string;

204

email?: string;

205

readonly createdAt: Date;

206

isActive: boolean;

207

avatar?: string;

208

};

209

210

// Get required writable properties

211

type RequiredWritableKeys = RequiredKeys<User> & WritableKeys<User>;

212

// Result: "name" | "isActive"

213

214

// Get optional readonly properties

215

type OptionalReadonlyKeys = OptionalKeys<User> & ReadonlyKeys<User>;

216

// Result: never (no properties are both optional and readonly in this example)

217

218

// Get all string properties that are writable

219

type WritableStringKeys = WritableKeys<User> & PickKeys<User, string>;

220

// Result: "name"

221

222

// Create update type with only writable properties

223

type UserUpdate = Partial<Pick<User, WritableKeys<User>>>;

224

// Result: { name?: string; email?: string; isActive?: boolean; avatar?: string; }

225

```

226

227

## Types

228

229

```typescript { .api }

230

type ReadonlyEquivalent<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2

231

? true

232

: false;

233

```