是否可以在 Python 中创建一个子状态类型来删除文字类型的第一部分?

问题描述 投票:0回答:0

我有一个 Python

Literal
类型,其中包含各种句点分隔的字符串。我还想有一个
Literal
类型,它包含相同的字符串但没有第一个以句点分隔的部分。我可以手动执行此操作,但我不想每次需要删除部分时都这样做。

from typing import Literal

# Period-delimited string literals
ActiveState = Literal['active.green', 'active.yellow', 'active.red']
State = ActiveState | OtherState | AnotherState # I'd like to do this with multiple

# Remove the first period-delimited section for when we're only looking at stuff after that
def handle_active_state(substate: Literal['green', 'yellow', 'red']) -> None: ...

我试过使用

typing.get_args
来迭代和修改
ActiveState
中的值,但是我无法找到在新的
Literal
类型中使用这些值的方法。我尝试使用
types.GenericAlias
重新创建
Literal
,但当我尝试使用它时,它认为结果是一个值而不是类型或类型别名。

from typing import Literal, get_args
from types import GenericAlias
ActiveState = Literal['active.green', 'active.yellow', 'active.red']

ActiveSubstate = GenericAlias(Literal, tuple('.'.join(state.split('.')[1:]) for state in get_args(ActiveState)))
# While this does generate Literal['green', 'yellow', 'red'], it's not usable

def handle_active_state(substate: ActiveSubstate) -> None: ...
# pylance: Illegal type annotation: variable not allowed unless it is a type alias
# Also encountered similar issue with mypy

我的目标是能够制作某种可自动执行此操作的可重用类型。例如,像

Substate[ActiveState]
这样的东西是理想的。这在 Python 中可能吗?如果不是,为什么不可能?

编辑:

这是为了静态类型分析。这种静态类型分析也适用于其他一些语言。 这个在 TypeScript 中工作的例子:

type ActiveState = 'active.green' | 'active.yellow' | 'active.red';
type Substate<T> = T extends `${infer First}.${infer After}` ? After : T;
type ActiveSubstate = Substate<ActiveState>;

const good: ActiveSubstate = 'green';
const bad: ActiveSubstate = 'blue'; // As expected: Type '"blue"' is not assignable to type 'ActiveSubstate'.
python types mypy pylance
© www.soinside.com 2019 - 2024. All rights reserved.