作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 TypeScript 的新手,我正面临一个非常微不足道的问题。我正在使用第三方电子邮件库,它包含在我控制的服务功能中。第三方功能以及我的服务功能接受具有通用电子邮件配置属性(收件人、发件人、主题、正文...)的对象,但第三方功能需要所有这些,而我的服务让 from 属性是可选的。见下文。
// Third Party Code
type ThirdPartyEmailData = {
from: string;
to: string;
subject: string;
body: string;
}
const sendEmailWithThirdPartyService = (emailData: ThirdPartyEmailData) => {
console.log('Sending email from:', emailData);
}
-----------------------------------------------------------------------------
// My Code
type MyEmailData = {
from?: string;
to: string;
subject: string;
body: string;
}
const sendEmail = (emailData: MyEmailData) => {
emailData = { from: 'info@company.com', ...emailData };
sendEmailWithThirdPartyService(emailData); // This does not compile
/**
* Argument of type 'MyEmailData' is not assignable to parameter of type 'ThirdPartyEmailData'.
* Property 'from' is optional in type 'MyEmailData' but required in type 'ThirdPartyEmailData'.
*/
}
sendEmail({
to: 'john.doe@customer.com',
subject: 'I <3 TypeScript',
body: 'But TypeScript hates me'
});
正如预期的那样,上面的代码无法编译,因为“MyEmailData”类型不能分配给“ThirdPartyEmailData”类型的参数。我一直在寻找一种干净的方法来转换/更改/转换 emailData 的类型,然后再将其传递给第三方函数,但我真的找不到好的方法。以下是我想到的一些东西,但感觉不太好。
方案一:直接转第三方类型
// My Code
const sendEmail = (emailData: MyEmailData) => {
// If you remove the line below the program still compiles but breaks at runtime
emailData = { from: 'info@company.com', ...emailData };
sendEmailWithThirdPartyService(<ThirdPartyEmailData>emailData); // This compiles
}
解决方案 2:使用类型保护来确保存在 from 属性
// My Code
const sendEmail = (emailData: MyEmailData) => {
emailData = { from: 'info@company.com', ...emailData };
// By using the type guard, we ensure that the type of emailData overlaps ThirdPartyEmailData
if (! hasFromProperty(emailData)) throw new Error('From property is missing');
sendEmailWithThirdPartyService(emailData); // This compiles
}
-----------------------------------------------------------------------------
// Utilities
/** Utility to make certain keys of a type required */
type RequiredKeys<T, K extends keyof T> = Exclude<T, K> & Required<Pick<T, K>>
/** Typeguard for property 'from' in MyEmailData */
const hasFromProperty = (data: MyEmailData): data is RequiredKeys<MyEmailData, 'from'> => {
return 'from' in data;
}
这看起来是一个非常普遍的问题,但我一直未能找到令人满意的解决方案。你能推荐什么?
最佳答案
你应该避免改变参数。对于您的情况,解决方案很简单:
const sendEmail = (emailData: MyEmailData) => {
const thirdPartyEmailData: ThirdPartyEmailData = { from: 'info@company.com', ...emailData };
sendEmailWithThirdPartyService(thirdPartyEmailData);
}
即使不声明 thirdPartyEmailData const thirdPartyEmailData = { from: 'info@company.com', ...emailData };
因为它是推断的类型,它也能工作。
关于TypeScript 将对象从具有可选属性的类型转换为不具有可选属性的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61726122/
我正在尝试用 Swift 编写这段 JavaScript 代码:k_combinations 到目前为止,我在 Swift 中有这个: import Foundation import Cocoa e
我是一名优秀的程序员,十分优秀!