Ограничения в софтверной инженерии созданы, чтобы их ломать. Годами меня бесил разрыв между Python и TypeScript: у одного невероятно динамичный и мощный рантайм, у другого невероятно динамичная и мощная система типов.
Так почему бы не совместить и то, и другое? 🔥
Встречайте PEP 827, результат годового ресерча о том, что нужно, чтобы прокачать type checking в Python до уровня его динамичности.
Вот как можно реализовать Record, сравнив варианты бок о бок:
TypeScript
type Record<K extends string, V> = {
[P in K]: V
}
// так что...
type Fruit = Record<
'apple' | 'banana' | 'orange',
string
>
// развернется в
//
// {
// apple: string;
// banana: string;
// orange: string;
// }Python
type Record[K, V] = NewTypedDict[
*[Member[k, V] for k in Iter[FromUnion[K]]]
]
# так что...
type Fruit = Record[
Literal["apple", "banana", "orange"],
str
]
# развернется в
#
# class <Fruit>:
# apple: str
# banana: str
# orange: str
Вот пример
Pick:TypeScript
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}Python
type Pick[T, K] = NewProtocol[*[
p for p in Iter[Attrs[T]]
if IsAssignable[p.name, K]
]]
А вот
Omit. Обрати внимание: версия на Python по сути не изменилась по сравнению с реализацией Pick, в отличие от TS.TypeScript
ts id="5ehk8a"
type Omit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
Python
py id="g6u8k1"
type Omit[T, K] = NewProtocol[*[
p for p in Iter[Attrs[T]]
if not IsAssignable[p.name, K]
]]
👉 @PythonPortal
