繁体   English   中英

具有数组联合类型的打字稿接口

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM