Typescript 如何基于超类型的对象创建子类型的对象?

Typescript 如何基于超类型的对象创建子类型的对象?,typescript,Typescript,我有一个超类型的对象compactUser,我想基于对象compactUser,以类型安全的方式创建一个子类型的对象detailedUser 我有一个有效的解决方案,detailedUser1在下面的代码中,但我希望更灵活的解决方案(按照detailedUser2)用于更复杂的场景 (抱歉,这看起来像是一个基本的打字问题,我确实在搜索解决方案,但最后还是在这里问了。) () 用户界面{ 身份证号码 } 接口详细信息服务器{ 身份证号码 名称:string 性别:弦 } const compact

我有一个超类型的对象
compactUser
,我想基于对象
compactUser
,以类型安全的方式创建一个子类型的对象
detailedUser

我有一个有效的解决方案,
detailedUser1
在下面的代码中,但我希望更灵活的解决方案(按照
detailedUser2
)用于更复杂的场景

(抱歉,这看起来像是一个基本的打字问题,我确实在搜索解决方案,但最后还是在这里问了。)

()

用户界面{
身份证号码
}
接口详细信息服务器{
身份证号码
名称:string
性别:弦
}
const compactUser:compactUser={id:1}
常量detailedUser1:detailedUser1={
…压缩用户,
名称:“nume”,
性别:'m',
}
//我不喜欢这样;它更灵活,但容易出错
const detailedUser2=compactUser作为DetailedUser
//ups,我设置了“性”,但忘记了“名字”`
detailedUser2.sex=Math.random()>0.5?“f':'m'
//不正常-我访问'name',并且没有键入脚本错误
console.log(detailedUser2.name)
我有一个有效的解决方案,
detailedUser1
在下面的代码中

您这样做的方式就是您这样做的方式,使用扩展符号,如您的示例所示:

const detailedUser1: DetailedUser = {
    ...compactUser,
    name: 'nume',
    sex: 'm',
};
…或
对象。分配

const detailedUser1: DetailedUser = Object.assign(
    {},
    compactUser,
    {
        name: 'nume',
        sex: 'm',
    }
};
其中,我认为传播是最明显和最常见的。请注意,这两个属性都保留了
compactUser
的所有属性,但在您的场景中
compactUser
仅具有适合
DetailedUser
的属性,因此这很好

如果有更复杂的场景,您可能希望将它们放在一个可重用的函数中,但它们基本上是相似的

我想要一些更灵活的东西(按照
detailedUser2

您的
detailsUser2
根本不做任何事情使对象适合该类型,它只是向TypeScript断言它是所需类型。从那时起,对象与其类型信息不同步,因为它没有
名称
性别
,但其类型表示它有:

console.log("sex" in detailedUser2); // false, but the type says it has to be true

这就是为什么您必须像为
detailedUser1
所做的那样做

如果要使用更新的类型信息重用同一对象,可以执行以下操作:

const detailedUser2: DetailedUser = Object.assign(compactUser, {name: "x", sex: "f"});
例如,提供缺失的属性。将
compactUser
更新到位。(同样,如果
compactUser
的属性
DetailedUser
没有,那么即使类型表示没有属性,它们也会存在;但在您的示例中,情况并非如此。)

您的
detailedUser1
方式和上面的
对象.assign
的优点之一是,如果您忘记了属性,TypeScript会告诉您:

const detailedUser2: DetailedUser = {...compactUser, {name: "x"});
//    ^^^^^^^^^^^^^-- Property 'sex' is missing in type 'CompactUser & { name: string; }' but required in type 'DetailedUser'.

我有一个有效的解决方案,
detailedUser1
在下面的代码中

您这样做的方式就是您这样做的方式,使用扩展符号,如您的示例所示:

const detailedUser1: DetailedUser = {
    ...compactUser,
    name: 'nume',
    sex: 'm',
};
…或
对象。分配

const detailedUser1: DetailedUser = Object.assign(
    {},
    compactUser,
    {
        name: 'nume',
        sex: 'm',
    }
};
其中,我认为传播是最明显和最常见的。请注意,这两个属性都保留了
compactUser
的所有属性,但在您的场景中
compactUser
仅具有适合
DetailedUser
的属性,因此这很好

如果有更复杂的场景,您可能希望将它们放在一个可重用的函数中,但它们基本上是相似的

我想要一些更灵活的东西(按照
detailedUser2

您的
detailsUser2
根本不做任何事情使对象适合该类型,它只是向TypeScript断言它是所需类型。从那时起,对象与其类型信息不同步,因为它没有
名称
性别
,但其类型表示它有:

console.log("sex" in detailedUser2); // false, but the type says it has to be true

这就是为什么您必须像为
detailedUser1
所做的那样做

如果要使用更新的类型信息重用同一对象,可以执行以下操作:

const detailedUser2: DetailedUser = Object.assign(compactUser, {name: "x", sex: "f"});
例如,提供缺失的属性。将
compactUser
更新到位。(同样,如果
compactUser
的属性
DetailedUser
没有,那么即使类型表示没有属性,它们也会存在;但在您的示例中,情况并非如此。)

您的
detailedUser1
方式和上面的
对象.assign
的优点之一是,如果您忘记了属性,TypeScript会告诉您:

const detailedUser2: DetailedUser = {...compactUser, {name: "x"});
//    ^^^^^^^^^^^^^-- Property 'sex' is missing in type 'CompactUser & { name: string; }' but required in type 'DetailedUser'.


我明白了,谢谢,也许值得一提的是,
Object.assign
将改变
compactUser
,即使
compactUser
(始终)和
detailedUser2
(可能)接收到其类型不具有的属性(代码位于.ly/2WU9Wk7)。我明白了,谢谢,也许值得一提的是,
Object.assign
将改变
compactUser
,即使
compactUser
(始终)和
detailedUser2
(可能)接收到其类型没有的属性(代码位于.ly/2WU9Wk7),也不会出现错误。