确保类型A扩展了具有作为另一个对象值的字段的类型B



我想确保类型A有一个泛型类型的字段,但该字段的名称是由另一个对象的字段值定义的。

例如功能:

interface IndexedContext<K extends string, T> {
context: T;
key: K;
}
type TypeB<P, K, T> = {
// this field should be named after IndexedContext[key]
P[K] = T;
}
const Consumer =
<T extends object, K>(context: IndexedContext<K, T>) => <C extends ComponentType<TypeA>, TypeA extends TypeB: C => {
.....
};

TypeA(props(应该有一个字段,该字段是IndexedKey中字段键的值?因此,当我在react组件上使用这个装饰器并向其传递ReactContext时,我可以确保props有一个与键相同的字段。

@Consumer({context: MyContext, key: 'myKey'})
class MyClass extends Component<MyProps> {}

interface MyProps {
// compiler should fail if this key is missing.
myKey: // Type of value of MyContext
}

您不需要定义任何额外的映射类型(例如示例中的TypeB(,您可以使用Record从字符串文字和字段类型中获得映射类型。

您还需要捕获实例类型,而不是构造函数。如果编写{context: MyContext, key: 'myKey'},则context将是类MyContext,因此T将被推断为typeof MyContext而不是MyContext。要获得实例类型,可以将context键入为new (...a:any[]) => T

综合起来:

interface IndexedContext<K extends string, T> {
context: Type<T>;
key: K;
}
type Type<T> = new (...a: any[]) => T
const Consumer =
<T extends object, K extends string>(context: IndexedContext<K, T>) => <C extends ComponentType<Record<K, T>>>(cls: C) => {
};
class MyContext { }
@Consumer({ context: MyContext, key: 'myKey' })
class MyClass extends Component<MyProps> { }

interface MyProps {
// compiler WILL fail if this key is missing.
myKey: MyContext// Type of value of MyContext
}

注意必须为context分配一个类才能工作,您将无法直接使用接口或基元。

相关内容

最新更新