问题描述
见Codesandbox
想法如下:
像这样:type IfType<If,Eq,T>
-
If
是一种string literal
,例如"Cat" | "Dog"
。 -
Eq
是提取出的If
字符串字面量,例如"Cat"
或"Dog"
-
T
是我想要返回的类型,如果传递的generic type
是特定类型的。
T
扩展了 object
,但如果 Eq
不是 equal
,则它返回 Partial<T>
,因此该类型仍然知道 {{1} } 键(用于解构)。
像这样:
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,and I don't kNow how to stop it
"read",{ hasRead: boolean}
>);
关于如何输入 helper util 类型的任何建议?
额外信息:我通常如何在没有 utils 类型的情况下输入它,这可以按我的意愿工作
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'.
解决方法
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
上的 constraint:
type IfType<
If extends string,// <-- no constraint here
T extends object
> = If extends Extract<If,Eq> ? T : Partial<T>
然后根据需要编译以下内容:
type Props<T extends Type> = { type: T } & (
IfType<T,{ 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,{ descriptionOnlyForWrite: string }>
| IfType<Type,{ hasRead: boolean }>
);
但我怀疑这对于您的用例是否真的有必要。毕竟,IfType
从来没有真正使用过 C
来计算输出类型;这只是对 If
和 Eq
的健全性检查。除非你有一些重要的理由这样做,否则我会完全取消对 Eq
的限制。