我想添加一个类型实用程序,它应该有条件地添加T
。
请参阅Codesandbox
想法如下:
类似这样的东西:type IfType<If, Eq, T>
If
是string literal
的一种类型,例如"Cat" | "Dog"
Eq
是提取的If
的字符串文字,例如"Cat"
或"Dog"
- 如果传递的
generic type
是特定类型的,则T
是我想要返回的类型
T
扩展了object
,但如果Eq
不是equal
,则返回Partial<T>
,因此该类型仍然知道object
密钥(用于析构函数(。
类似这样的东西:
util.ts
type IfType<
If extends string,
Eq extends If,
T extends object
> = If extends Extract<If, Eq> ? T : Partial<T>
otherfile.ts
type Type = 'read' | 'write';
type Props<T extends Type> = {
type: T
} & (
IfType<
T,
// This gets the ts(2344) error, and I don't know how to stop it
"write",
{ descriptionOnlyForWrite: string }
>
| IfType<
T,
// This gets the ts(2344) error, and I don't know how to stop it
"read",
{ hasRead: boolean}
>);
这给出了以下错误:
Type '"write"' does not satisfy the constraint 'T'.
'"write"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Type'.
关于如何键入helper util类型,有什么建议吗?
额外信息:如果没有utils类型,我通常会如何键入它,它可以按照我的要求工作
type Type = 'read' | 'write';
type Props<T extends Type> = {
type: T;
} & (
| (T extends 'write' ? { descriptionOnlyForWrite: string } : { descriptionOnlyForWrite?: undefined })
| (T extends 'read' ? { hasRead: boolean } : { hasRead?: undefined })
);
T extends Type
和"write" extends Type
并不意味着"write" extends T
。考虑当T
是"read"
(作为Props<"read">
(时会发生什么;"write" extends "read"
不是真的,所以编译器抱怨IfType<T, "write", XXX>
可能无效。
看起来你并不是真的希望IfType<If, Eq, T>
需要Eq extends If
。假设你不想让IfType
变得更复杂,你可以去掉对Eq
:的限制
type IfType<
If extends string,
Eq, // <-- no constraint here
T extends object
> = If extends Extract<If, Eq> ? T : Partial<T>
然后根据需要编译以下内容:
type Props<T extends Type> = { type: T } & (
IfType<T, "write", { descriptionOnlyForWrite: string }>
| IfType<T, "read", { hasRead: boolean }>
);
如果您真的关心在If
和Eq
上表达约束,则需要将该约束作为单独的类型参数C
传递给IfType
:
type IfType<
C extends string,
If extends C,
Eq extends C,
T extends object
> = If extends Extract<If, Eq> ? T : Partial<T>
type Props<T extends Type> = { type: T } & (
IfType<Type, T, "write", { descriptionOnlyForWrite: string }>
| IfType<Type, T, "read", { hasRead: boolean }>
);
但我怀疑这对于您的用例是否真的有必要。毕竟,IfType
从未实际使用C
来计算输出类型;这只是对CCD_ 38和CCD_。除非你有什么重要的理由这样做,否则我只会完全取消对Eq
的限制。
游乐场链接到代码