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>
无法检测到您设置了true
还是{{1 }}
是否可以纠正我的解决方案,或者这是TS中的限制?
答案 0 :(得分:0)
如果值是可变的(并且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 }
,则该对象仍是可变的),Typescript将不使用文字。
最简单的解决方案是使用将推断属性的正确文字类型的函数来更改创建对象的方式:
<pre>
var nodemailer = require("nodemailer");
sails.log.debug("try to send mail");
var smtpTransport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
XOAuth2: {
user: "xxx@gmail.com", // Your gmail address.
clientId: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
refreshToken: "REFRESH_TOKEN_YOU_JUST_FOUND"
}
}
});
var mailOptions = {
from: "xxx@gmail.com", // sender address
to: RECEIVER_EMAIL", // list of receivers
subject: "A_SUBJECT", // Subject line
// text: ", // plaintext body
html: htmlBody // html body
};
// send mail
smtpTransport.sendMail(mailOptions, function(error, info) {
if (error) {
sails.log.debug(error);
return res.notOk({
status: "error",
msg: "Email sending failed"
})
} else {
console.log("Message %s sent: %s", info.messageId, info.response);
return res.ok({
status: "ok",
msg: "Email sent"
})
}
smtpTransport.close();
});
</pre>
答案 1 :(得分:0)
您可以在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)