代码之家  ›  专栏  ›  技术社区  ›  ed'

从对象推断(没有类型加宽)属性

  •  0
  • ed'  · 技术社区  · 6 年前
    • 我有一种类型 MrType<T extends boolean>
    • 我有一个功能 MrFn(obj?: { lol: boolean }): MrType<typeof obj.lol>

    我试图推断 lol 提供的对象(如果完全提供)的属性为 true false

    但是我撞到了一堵墙,因为类型变宽了。

    type Magic<T> = T extends { lol: infer U } ? U : false;
    
    const trueObj = { lol: true };
    const falseObj = { lol: false };
    
    // should pass
    const a: Magic<typeof trueObj> = true; // ok
    const b: Magic<typeof falseObj> = false; // ok
    const c: Magic<{ lol: true }> = true; // ok
    const d: Magic<{ lol: false }> = false; // ok
    
    // should fail
    const e: Magic<typeof falseObj> = true; // does not fail
    const f: Magic<typeof trueObj> = false; // does not fail
    const g: Magic<{ lol: false }> = true; // ok (fails)
    const h: Magic<{ lol: true }> = false; // ok (fails)
    

    我的 trueObj falseObj 将其属性推断为 boolean 也就是说我的 Magic<T> 无法检测是否设置

    有没有办法纠正我的解决方案,或者这是TS中的一个限制?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Titian Cernicova-Dragomir    6 年前

    如果值是可变的(尽管 trueObj const 对象仍然是可变的)。

    最简单的解决方案是更改创建对象的方式,使用一个函数来推断属性的正确文本类型:

    function makeLol<T extends boolean>(o: { lol: T }) {
        return o
    }
    const trueObj = makeLol({ lol: true }); // typed as { lol: true }
    const falseObj = makeLol({ lol: false }); // typed as { lol: false }