扩展字符串文字的条件类型 想法如下:

问题描述

我想添加一个类型实用程序,它有条件地应该添加 T

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 }>
);

如果您真的关心在 IfEq 上表达约束,则需要将该约束作为单独的类型参数 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 来计算输出类型;这只是对 IfEq 的健全性检查。除非你有一些重要的理由这样做,否则我会完全取消对 Eq 的限制。

Playground link to code