搜索词
partial, nonnullable, required, undefined
建议
这可能看起来像#13195的重复问题,但这个问题与TS引擎不同,因为它不需要可能破坏性的更改。
相反,它利用了一个特殊的泛型Partial类型,该类型不允许显式设置null/undefined。
// these of course sadly don't work
type NonNullablePartial<T> = {
[P in keyof T]?: NonNullable<T[P]>;
};
type NonNullablePartial<T> = {
[P in keyof T]?: T[P] extends null | undefined | infer R ? R : T[P];
};
我的建议通过防止可能的错误来增加类型安全性,而目前使用Partial的实现还不能做到这一点。
用例
这个问题的原因在于,显式的null
/ undefined
阻止了将这些模式应用到"默认"参数上。
这个模式并不受此影响,一个显式设置的undefined
会被重新分配给一个默认参数。然而,这种模式对于大量的配置变量来说是不切实际的。
function f({ message = 'message' } = {}) {
console.log(message)
}
f({ message: undefined }); // message - correct!
f({ message: null }); // null - this makes sense, though not what I am looking for
换句话说:
我正在使用一个默认的配置对象,然后需要将其与用户的配置对象合并。我需要防止用户可能错误地将null
/ undefined
值分配给参数,从而实际上替换并删除"默认"值。
示例
export interface ResponseErrorTemplate {
code: string;
status: number;
message: string;
errorConstructor: typeof ApolloError;
}
export interface ResponseErrorTemplateInput {
message: string;
errorConstructor: typeof ApolloError;
}
export type ResponseErrorTemplateGetter = (
config?: Partial<ResponseErrorTemplateInput> // Here, keep Partial, but prevent null/undefined
) => ResponseErrorTemplate;
const defaultConfig: ResponseErrorTemplateInput = {
message: 'Not found',
errorConstructor: ApolloError,
};
export const getNotFoundTemplate: ResponseErrorTemplateGetter = config => ({
...defaultConfig,
...config, // if user defines message: undefined here, they replace the default 'Not found'
status: 404,
code: 'NOT_FOUND',
});
检查清单
我的建议满足以下准则:
- 这不会对现有的TypeScript/JavaScript代码造成破坏性的更改
- 这不会改变现有JavaScript代码的运行时行为
- 这可以在不根据表达式的类型发出不同的JS的情况下实现
- 这不是一个运行时特性(例如库功能、JavaScript输出的非ECMAScript语法等)
- 这个特性将与TypeScript's Design Goals的其他部分保持一致。
2条答案
按热度按时间abithluo1#
我也需要这个。你可以看到Typescript文档中的示例是错误的:
https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt
todo2
被推断为Todo
,但生成的是Partial<Todo>
你可以在 https://www.typescriptlang.org/play/index.html#code/JYOwLgpgTgZghgYwgAgCoHsAm7kG8CwAUMicmMGADYQBcyAzmFKAOYDcRpymE9CzAB3LoQdRsxDsiAXyJEYAVxAJhIZAoGY4kDNgAUYLOjq70AGmQxgESpnoYAqpu21kABThRycSgB5TAHwAlDSmBMSkUBBgClBquMgAdMmG2BbJiVY2do7OkMjSHISyhEQIIoxkRgCMyAC8eJyk5FSuAOToUCxwIMAAXig89ADWbWZNJEP8wELAInRtCNSeyEsKYJBQYzJFZRVgVdgATPXqeRCmBjUW4Vwt1HRKPFYgEJjjEZO807PzyG1gAAWUHQAHdkOh1mQoHB6IDtsUgrtCOUQPR0NREpR0CwrsckUA
如果你传递第二个参数为
undefined
,你会得到一个Partial<Todo>
:这是@ackvf所说的,但是使用Typescript文档中的示例。
使用场景:
拥有多语言应用,允许更改其中的一些内容,
setMessages(someMessages: PartialNotNull<Messages>)
警告,所以你不应该去undefined,因为这些消息将不会显示。rdrgkggo2#
我也更新了我的留言,以便更好地解释意图。简而言之:
我需要阻止用户创建属性
undefined
,因为它们会替换默认配置对象中的配置值。