[英]typescript interface with array union type
似乎这个联合类型的标志数组对我来说并不适用。 我一直在考虑实现类必须提供关于它正在实现的接口的标志,这也很容易从实现类中脱离出来。 标志作为flags: Record<T & FeatureFlagType, true>
有效,但这也适用于数组上下文? 我已经尝试了所有不同的标志组合,如 (T & FeatureFlag)[] 但似乎没有任何效果。
type FeatureFlagType = 'feature1' | 'feature2';
interface FeatureFlag<T extends FeatureFlagType> {
flags: T[];
flagsRecords: Record<T, true>;
}
interface Feature1 extends FeatureFlag<'feature1'> {
doFeature1: () => void;
}
interface Feature2 extends FeatureFlag<'feature2'> {
doFeature2: () => void;
}
class Instance implements Feature1, Feature2 {
public flags = ['feature1' as 'feature1', 'feature2' as 'feature2']; // not ok
public flagsRecords = {feature1: true as true, feature2: true as true}; // this is ok
public doFeature1() {
}
public doFeature2() {
}
}
implements
强制类型的交集。 这里的问题是:
'a'[] & 'b'[] // never
所以这行不通。 您想要的是flags
数组的字符串联合,但implements
不会为您执行此操作。
但是,交叉点将与记录一起使用:
Record<'a', string> & Record<'b', string> // { a: string, b: string }
这是另一种方法:
// See: https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type FeatureFlagType = 'feature1' | 'feature2';
interface FeatureFlag<T extends FeatureFlagType> {
flag: T;
}
type HasFeatures<T extends FeatureFlag<FeatureFlagType>[]> =
{ flags: T[number]['flag'][] }
& UnionToIntersection<Omit<T[number], 'flag'>>
// intended usage:
class A implements HasFeatures<[Feature1, Feature2]> {
//...
}
现在每个功能都有一个标志。 HasFeatures
接受一个特征数组,并将所有可能的特征组成一个数组作为flags
属性。
然后将所有非flag
属性相交并与类型合并,因此类型得到所有特征接口。
(为了得到特征接口数组的交集,需要一些巫术)
但是现在这可以按您的预期工作:
interface Feature1 extends FeatureFlag<'feature1'> {
doFeature1: () => void;
}
interface Feature2 extends FeatureFlag<'feature2'> {
doFeature2: () => void;
}
class Instance implements HasFeatures<[Feature1, Feature2]> {
public flags = [
'feature1' as const,
'feature2' as const
];
public doFeature1() {
}
public doFeature2() {
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.