Skip to content

Commit 9345131

Browse files
codewizdaveclaude
andauthored
Add type utilities: KeyOf, Template, DeepPartial, Partial, Required, Pick, Omit (#17)
* Add type utilities: KeyOf, Template, DeepPartial, Partial, Required, Pick, Omit Add the following type utilities: - KeyOf[T]: Returns all member names as a tuple of Literal types - Template[*Parts]: Template literal string builder - DeepPartial[T]: Make all fields recursively optional - Partial[T]: Make all fields optional (non-recursive) - Required[T]: Remove Optional from all fields - Pick[T, K]: Pick specific fields from a type - Omit[T, K]: Omit specific fields from a type Add comprehensive tests for all new types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add comprehensive tests for type utilities - Add more complex tests for KeyOf (order preservation) - Add more tests for DeepPartial (optional fields, type preservation) - Add more tests for Partial (union types) - Add more tests for Required (multiple optionals) - Add more tests for Pick (single-element tuples) - Add more tests for Omit (single-element tuples, all fields omitted) - Add Template tests (basic functionality verification) Total: 155 tests passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Bump version to 0.2.0 and add release documentation - Update version from 0.1.2 to 0.2.0 - Add CHANGELOG.md with release notes - Add examples for new type utilities in README.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a802a6b commit 9345131

6 files changed

Lines changed: 1041 additions & 1 deletion

File tree

packages/typemap/CHANGELOG.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [0.2.0] - 2026-03-05
6+
7+
### Added
8+
9+
- **KeyOf[T]** - Returns all member names as a tuple of Literal types
10+
- Similar to TypeScript's `keyof` operator
11+
- Example: `KeyOf[User]` returns `tuple[Literal["name"], Literal["age"]]`
12+
13+
- **Template[*Parts]** - Template literal string builder
14+
- Concatenates string literal types at runtime
15+
- Example: `Template["api/v1/", Literal["users"]]` returns `Literal["api/v1/users"]`
16+
17+
- **DeepPartial[T]** - Make all fields recursively optional
18+
- Applies optional transformation to all nested types
19+
- Example: `DeepPartial[User]` makes all nested fields optional
20+
21+
- **Partial[T]** - Make all fields optional (non-recursive)
22+
- Makes all top-level fields optional without recursion
23+
- Example: `Partial[User]` returns `name: str | None, age: int | None`
24+
25+
- **Required[T]** - Remove Optional from all fields
26+
- Inverse operation of Partial
27+
- Example: `Required[OptionalUser]` removes `| None` from all fields
28+
29+
- **Pick[T, K]** - Pick specific fields from a type
30+
- Creates a new type with only the specified fields
31+
- Example: `Pick[User, tuple["name", "email"]]`
32+
33+
- **Omit[T, K]** - Omit specific fields from a type
34+
- Creates a new type excluding specified fields
35+
- Example: `Omit[User, tuple["password"]]`
36+
37+
### Changed
38+
39+
- Updated `typemap_extensions` to export all new type utilities
40+
41+
## [0.1.2] - 2026-03-04
42+
43+
### Added
44+
45+
- Initial release with core type evaluation
46+
- Support for PEP 827 type manipulation
47+
- `eval_typing` function for runtime type evaluation
48+
- Core type operators: Member, Attrs, Iter, Param, UpdateClass, NewProtocol, IsAssignable

packages/typemap/README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ typemap provides utilities for working with [PEP 827](https://peps.python.org/pe
2121
- `UpdateClass` - Generate class modifications
2222
- `NewProtocol` - Create protocols dynamically
2323
- `IsAssignable` - Check type assignability
24+
- `KeyOf` - Get all member names as tuple of Literals
25+
- `Template` - Build template literal strings
26+
- `DeepPartial` - Make all fields recursively optional
27+
- `Partial` - Make all fields optional (non-recursive)
28+
- `Required` - Remove Optional from all fields
29+
- `Pick` - Pick specific fields from a type
30+
- `Omit` - Omit specific fields from a type
2431

2532
## Usage
2633

@@ -37,6 +44,47 @@ result = eval_typing(MyClass)
3744
print(result)
3845
```
3946

47+
### Type Utilities
48+
49+
typemap provides several type utility operators for transforming types:
50+
51+
```python
52+
from typing import Literal
53+
import typemap_extensions as tm
54+
55+
# KeyOf - Get all member names as tuple of Literals
56+
class User:
57+
name: str
58+
age: int
59+
60+
keys = tm.KeyOf[User]
61+
# Result: tuple[Literal["name"], Literal["age"]]
62+
63+
# Partial - Make all fields optional (non-recursive)
64+
PartialUser = tm.Partial[User]
65+
# Result: class with name: str | None, age: int | None
66+
67+
# DeepPartial - Make all fields recursively optional
68+
DeepUser = tm.DeepPartial[User]
69+
# Result: class with all nested fields optional
70+
71+
# Required - Remove Optional from all fields
72+
class OptionalUser:
73+
name: str | None
74+
age: int | None
75+
76+
RequiredUser = tm.Required[OptionalUser]
77+
# Result: class with name: str, age: int
78+
79+
# Pick - Select specific fields
80+
PublicUser = tm.Pick[User, tuple["name"]]
81+
# Result: class with only name: str
82+
83+
# Omit - Exclude specific fields
84+
SafeUser = tm.Omit[User, tuple["password"]]
85+
# Result: class without password field
86+
```
87+
4088
### Using UpdateClass
4189

4290
```python

packages/typemap/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "typemap"
3-
version = "0.1.2"
3+
version = "0.2.0"
44
description = "PEP 827 type manipulation library"
55
requires-python = ">=3.14"
66
dependencies = [

0 commit comments

Comments
 (0)