gpt4 book ai didi

javascript - Typescript 查找类型 - 在与 Partial 合并时正确缩小属性集

转载 作者:搜寻专家 更新时间:2023-10-30 21:12:33 24 4
gpt4 key购买 nike

我正在研究查找类型并想构建一种安全合并实用程序函数(一个接受类型为 T 的实体和一个包含 T< 的键子集的对象 更新)。我的目标是让编译器在我拼错属性或尝试为 T 附加不存在的属性时告诉我。

所以我有 Person 并在 (v2.1) 中使用内置的 Partial,如下所示:

interface Person {
name: string
age: number
active: boolean
}

function mergeAsNew<T>(a: T, b: Partial<T>): T {
return Object.assign({}, a, b);
}

现在我将其应用于以下数据:

let p: Person = {
name: 'john',
age: 33,
active: false
};

let newPropsOk = {
name: 'john doe',
active: true
};

let newPropsErr = {
fullname: 'john doe',
enabled: true
};

mergeAsNew(p, newPropsOk);
mergeAsNew(p, newPropsErr); // <----- I want tsc to yell at me here because of trying to assign non-existing props

我希望 TS 编译器在第二次调用时对我大喊大叫,因为 fullnameenabled 不是 Person 的属性。不幸的是,这在本地编译得很好,但是......当我在 online TS Playground 中做同样的事情时我或多或少得到了我所期望的:

The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'Person' is not a valid type argument because it is not a supertype of candidate '{ fullname: string; enabled: boolean; }'.
Property 'name' is missing in type '{ fullname: string; enabled: boolean; }'.

看起来 playground 使用的版本与我在本地使用的版本相同 (2.1.4)。有谁知道为什么这两者可能不同?

奖励问题:

当我尝试以下作业时:

let x: Person = mergeAsNew(p, newPropsOk);

我在 x 上收到以下错误,但仅在 Playground 上(在本地一切正常):

Type '{ name: string; active: boolean; }' is not assignable to type 'Person'.
Property 'age' is missing in type '{ name: string; active: boolean; }'.

这是为什么呢?它不应该 Person 类型,因为第一个 mergeAsNew 参数 Person并且其他所有内容都是 Person-props 子集(所以它最多是 Person)?

编辑这是我的 tsconfig.json:

{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"noEmitOnError": true,
"allowJs": false,
"sourceMap": true,
"strictNullChecks": true
},
"exclude": ["dist", "scripts"]
}

最佳答案

当你想表达一种类型只有另一种类型的属性子集时,普通的 extends 也可以提供帮助

interface Person {
name: string
age: number
active: boolean
}


let p: Person = {
name: 'john',
age: 33,
active: false
};

let newPropsOk = {
name: 'john doe',
active: true
};

let newPropsErr = {
fullname: 'john doe',
enabled: true
};

// a extends b and not the other way round
//because we don't want to allow b to have properties not in a
function mergeAsNew<T2, T1 extends T2>(a: T1, b: T2): T1 {
return Object.assign({}, a, b);
}

mergeAsNew(p, newPropsOk); // ok
mergeAsNew(p, newPropsErr);
// Argument of type 'Person' is not assignable
// to parameter of type '{ fullname: string; enabled: boolean; }'.
// Property 'fullname' is missing in type 'Person'.

PS 不知道 playground 和映射类型发生了什么

关于javascript - Typescript 查找类型 - 在与 Partial 合并时正确缩小属性集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41599505/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com