首页 文章

在Typescript中区分私有成员联盟

提问于
浏览
3

我've got a little problem with discriminating private class members'类型 . 我正在尝试使用字符串文字访问变量 v1v2 ,但typescript返回一个类型联合 . 我设法通过给一些打字稿"push"来解决这个问题 . 坏消息是它只适用于公众成员 . 请参阅以下示例:

class Test {
    private v1: string;
    private v2: number;
    v3: string;
    v4: number;
    private v5: string;
    private v6: number;

    // Works for all members, but does not discriminate union
    get12(what: 'v1' | 'v2') {
        return this[what];
    }

    // Works only for public members
    get34<T extends 'v3' | 'v4'>(what: T) {
        return this[what];
    }

    // Explicit overload works, but it defeats the purpose of being lazy
    get56(what: 'v5'): string;
    get56(what: 'v6'): number;
    get56(what: 'v5' | 'v6') {
        return this[what];
    }
}

let myTest = new Test();
myTest.get12('v1'); // returns "string | number" type
myTest.get34('v3'); // returns "string" type
myTest.get56('v5'); // returns "string" type

有谁知道某种解决方法?

Edit: 为了澄清,我正在寻找一个懒惰/通用的解决方案 . 还有其他方法可以实现我想要的,但是它们都需要我在变量类型更改的情况下维护它们(例如,显式重载) .

1 回答

  • 3

    Bleggh,这似乎是TypeScript的一个design limitation,在某些具有私有属性的情况下你不能使用索引访问 . 不知道如何最好地导航这个 .

    这是"works",但我不建议实际做到这一点:

    //@ts-ignore
    type UnsafeIndexed<T, K extends string> = T[K]
    

    以上是一个故意错误的类型别名,要求编译器进行索引访问,即使它不能确定这样的事情是否有效 . 看看吧:

    type Foo = { bar: string, baz: number };
    type FooBar = UnsafeIndexed<Foo, "bar">; // string
    type FooBaz = UnsafeIndexed<Foo, "baz">; // number
    type FooBad = UnsafeIndexed<Foo, "nope">; // any
    

    现在你可以这样做:

    class Test {
        private v1: string;
        private v2: number;
    
        get<K extends 'v1' | 'v2'>(what: K): UnsafeIndexed<this,K> {
            return (this as any)[what];
        }
    }
    

    请注意,您必须执行 (this as any) ,因为 this[what] 仍然会引发编译器错误 . 测试一下:

    let myTest = new Test();
    const v1 = myTest.get('v1'); // string
    const v2 = myTest.get('v2'); // number
    

    好吧,就像我说的那样“有效” . 但我不希望那些感人的 生产环境 代码 . 我不知道是否有一个较为邪恶的解决方法是通用的 . 就个人而言,我要么只使用公共属性或重载 . 你的旅费可能会改变 .

    希望有所帮助 . 祝好运!

相关问题