Ben*_*n M 9 generics partial typescript
如何创建一个还挺 - Partial<T>类型,不允许undefined值?
这是一个例子:
interface MyType {
foo: string
bar?: number
}
const merge = (value1: MyType, value2: KindaPartial<MyType>): MyType => {
return {...value1, ...value2};
}
const value = {
foo: 'foo',
bar: 42
}
merge(value, {}); // should work
merge(value, { foo: 'bar' }); // should work
merge(value, { bar: undefined }); // should work
merge(value, { bar: 666 }); // should work
merge(value, { foo: '', bar: undefined }); // should work
merge(value, { foo: '', bar: 666 }); // should work
// now the problematic case:
merge(value, { foo: undefined }); // this should throw an error
// because MyType["foo"] is of type string
Run Code Online (Sandbox Code Playgroud)
我要寻找的类型应该是:
Partial<T>)undefined,如果泛型类型不接受undefined该键这可能吗?
编辑:我还在TypeScript存储库中创建了一个问题,因为这很奇怪,并且在某个时候应该抛出错误:https : //github.com/Microsoft/TypeScript/issues/29701
jca*_*alz 13
它是一种已知的限制在于打字稿不正确地被对象属性(和功能参数)之间进行区分缺少从那些与是存在的,但undefined。Partial<T>允许undefined属性的事实是其结果。正确的做法是等到解决此问题为止(如果您在GitHub中处理该问题并给它一个或一个令人信服的用例发表评论,则可能会出现这种情况)。
如果您不想等待,则可以使用以下黑客方式获得类似此行为的信息:
type VerifyKindaPartial<T, KP> =
Partial<T> & {[K in keyof KP]-?: K extends keyof T ? T[K] : never};
const merge = <KP>(value1: MyType, value2: KP & VerifyKindaPartial<MyType, KP>): MyType => {
return { ...value1, ...value2 };
}
Run Code Online (Sandbox Code Playgroud)
所以你不能KindaPartial<T>直接写。但是,您可以编写一个类型VerifyKindaPartial<T, KP>,该类型 接受要与您的预期对象核对的类型T和候选类型。如果候选人匹配,则返回匹配的内容。否则,它将返回不包含的内容。 KPKindaPartial<T>KP
然后,您可以创建merge()一个通用函数,KP该函数根据传入的值的类型进行推断value2。如果KP & VerifyKindaPartial<MyType, KP>匹配KP(表示KP匹配KindaPartial<MyType>),则代码将编译。否则,如果KP & VerifyKindaPartial<MyType, KP>它不匹配KP(意思是KP不匹配KindaPartial<MyType>),那么将是一个错误。(但是,该错误可能不是很直观)。
让我们来看看:
merge(value, {}); // works
merge(value, { foo: 'bar' }); // works
merge(value, { bar: undefined }); // works
merge(value, { bar: 666 }); // works
merge(value, { foo: '', bar: undefined }); // works
merge(value, { foo: '', bar: 666 }); // works
merge(value, { foo: undefined }); // error!
// ~~~ <-- undefined is not assignable to never
// the expected type comes from property 'foo',
Run Code Online (Sandbox Code Playgroud)
这具有您想要的行为...尽管您得到的错误有点怪异(理想情况下,它会说这undefined不可分配给string,但是问题是编译器知道传入的类型为undefined,并且它希望该类型为是string的,所以编译器相交这些来undefined & string是never。哦。
无论如何,这里可能有一些警告。泛型函数在直接调用时可以很好地工作,但它们的组合效果不好,因为TypeScript对种类较多的类型的支持不是那么好。我不知道这是否真的适合您的用例,但这是我目前能用的最好的语言。
希望能有所帮助;祝好运!
在这种情况下,Pick应该可以工作。
interface MyType {
foo: string
bar?: number
}
const merge = <K extends keyof MyType>(value1: MyType, value2: Pick<MyType, K>): MyType => {
return {...value1, ...value2};
}
merge(value, {}); // ok
merge(value, { foo: 'bar' }); // ok
merge(value, { bar: undefined }); // ok
merge(value, { bar: 666 }); // ok
merge(value, { foo: '', bar: undefined }); // ok
merge(value, { foo: '', bar: 666 }); // ok
merge(value, { foo: undefined }); // ng
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1386 次 |
| 最近记录: |