首页 > 解决方案 > 从对象推断(不扩展类型)属性

问题描述

我试图推断lol提供的对象上的属性(如果提供的话)是truefalse

但是,由于类型变宽,我撞到了墙

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)

MytrueObjfalseObjget 它们的属性推断为boolean,这意味着 myMagic<T>无法检测您是否设置truefalse

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

标签: typescript

解决方案


你可以在 TypeScript 3.4+ 中使用新的as const类型断言来做到这一点:

type Magic<T> = T extends { lol: infer U } ? U : false;

const trueObj = { lol: true } as const;
const falseObj = { lol: false } as const;

// 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; // ok (fails)
const f: Magic<typeof trueObj> = false; // ok (fails)
const g: Magic<{ lol: false }> = true; // ok (fails)
const h: Magic<{ lol: true }> = false; // ok (fails)

推荐阅读