【发布时间】:2022-11-22 20:45:50
【问题描述】:
问题定义
假设我们有一个 React 组件 C 接受属性 Props。 Props 有一个名为edges 的字段。 Edges 被定义为长度为 1-4 的元组,由字符串文字 top、bottom、left、right 组成。
任务:将 edges 参数限制为没有重复的元组。
例如。:
这应该编译得很好:
<C edges={['top', 'bottom']} />
虽然这应该会失败:
<C edges={['top', 'top']} />
到目前为止我所拥有的
// Our domain types
type Top = 'top';
type Bottom = 'bottom';
type Left = 'left';
type Right = 'right';
type Edge = Top | Bottom | Left | Right;
// A helper types that determines if a certain tuple contains duplicate values
type HasDuplicate<TUPLE> = TUPLE extends [infer FIRST, infer SECOND]
? FIRST extends SECOND
? SECOND extends FIRST
? true
: false
: false
: TUPLE extends [first: infer FIRST, ...rest: infer REST]
? Contains<FIRST, REST> extends true
? true
: HasDuplicate<REST>
: never;
// Just some helper type for convenience
type Contains<X, TUPLE> = TUPLE extends [infer A]
? X extends A
? A extends X
? true
: false
: false
: TUPLE extends [a: infer A, ...rest: infer REST]
? X extends A
? A extends X
? true
: Contains<X, REST>
: Contains<X, REST>
: never;
通过以上我已经可以得到这个:
type DoesNotHaveDuplicates = HasDuplicate<[1, 2, 3]>; // === false
type DoesHaveDuplicates = HasDuplicate<[1, 0, 2, 1]>; // === true
我被困在哪里
假设我们有一个组件 C:
// For simple testing purposes, case of a 3-value tuple
type MockType<ARG> = ARG extends [infer T1, infer T2, infer T3]
? HasDuplicate<[T1, T2, T3]> extends true
? never
: [T1, T2, T3]
: never;
interface Props<T> {
edges: MockType<T>;
}
function C<T extends Edge[]>(props: Props<T>) {
return null;
}
上面的工作,但只是这样的:
// this compiles:
<C<[Top, Left, Right]> edges={['top', 'left', 'right']} />
// this does not (as expected):
<C<[Top, Left, Left]> edges={['top', 'left', 'left']} />
我无法弄清楚的是如何摆脱组件实例化中的泛型,并使打字稿根据提供给 edges 属性的值在编译时推断出类型。
【问题讨论】:
-
如果 this 有效,请告诉我。没有明确的泛型
标签: reactjs typescript tuples