首页 > 解决方案 > 在使用 lodash 的 partialRight 创建的部分函数上解决未设置的“长度”属性

问题描述

我正在使用MomentTimezone在浏览器中进行时间操作。

我也在使用 TypeScript 和Lodash

我对包含经过身份验证的用户的首选时区进行了一些accountTimezone设置。window我正在尝试创建一个辅助方法localMoment(),该方法将接受的许多签名中的moment.tz()window.accountTimezone任何一个,并将其作为最终timezone: string参数附加。

这似乎partialRight是我正在寻找的东西。

const localMoment = partialRight(moment.tz, window.accountTimezone);

我遇到的问题与 lodash 文档中的这个注释有关:

注意:此方法不设置部分应用函数的“长度”属性。

具体来说,对于类似的调用localMoment('2019-08-01 12:00:00'),TypeScript 抱怨localMoment()提供了 1 个参数,但期望为零。

我怎样才能让 TypeScript 愉快地理解调用localMoment()应该看起来像moment.tz()通过MomentTimzone接口调用,同时避免使用partialRight()?


我考虑过这样的替代方案,但不知道如何打字...args才能让 TypeScript 满意。

const localMoment = (...args): Moment => moment.tz(...args, window.accountTimezone);

标签: javascripttypescriptlodash

解决方案


没有干净的方法可以做到这一点。您必须选择不输入或重新声明自己的界面。

Typescript 自己无法做到这一点,只能选择声明一堆不同签名的“足够好”的解决方案: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/lodash/common/function。 d.ts#L1147

即使您以某种方式设法操纵打字稿界面,我怀疑您是否可以处理没有时区参数 的其他方法( zone, add, , ...): https ://github.com/DefinitelyTyped/DefinitelyTyped/blob/ master/types/moment-timezone/moment-timezone.d.ts#L20link

Pick您可以实现的最佳效果是避免使用实用程序类型复制整个界面:

type CurriedMomentTimezone = Pick<moment.MomentTimezone, 'zone' | 'add' | 'link' | 'load' | 'names' | 'guess' | 'setDefault'> & {
    (): moment.Moment;
    (date: number): moment.Moment;
    (date: number[]): moment.Moment;
    (date: string): moment.Moment;
    (date: string, format: moment.MomentFormatSpecification): moment.Moment;
    (date: string, format: moment.MomentFormatSpecification, strict: boolean): moment.Moment;
    (date: string, format: moment.MomentFormatSpecification, language: string): moment.Moment;
    (date: string, format: moment.MomentFormatSpecification, language: string, strict: boolean): moment.Moment;
    (date: Date): moment.Moment;
    (date: moment.Moment): moment.Moment;
    (date: any): moment.Moment;
}

localMoment = _.partialRight(moment.tz, this.accountTimezone) as CurriedMomentTimezone;

推荐阅读