【问题标题】:Limit array values based on interface used as return根据用作返回的接口限制数组值
【发布时间】:2020-10-13 11:11:37
【问题描述】:

我有这个代码:

export interface StoreCursor {
    created: Date;
    id: number;
}

export default class PageUtil {
    public static decode<T>(cursor?: string, dates?: (keyof T)[]): T | undefined {
        if (!cursor) {
            return;
        }

        const json = Buffer.from(cursor, "base64").toString("utf8");

        return JSON.parse(json, (key, value) => (dates?.includes(key) ? new Date(value) : value));
    }
}

const decoded = PageUtil.decode<StoreCursor>(cursor, ["created"]);

但我得到下一个错误,我不知道如何解决它:

错误 TS2345:“字符串”类型的参数不可分配给“keyof T”类型的参数。

我也试过了:

public static decode<T>(cursor?: string, dates?: (keyof T & string)[]): T | undefined {
    [...]
}

但错误类似:

错误 TS2345:'string' 类型的参数不可分配给'keyof T & string' 类型的参数。 类型 'string' 不可分配给类型 'keyof T'。

我希望 dates 仅限于 StoreCursor 的键(或者更好,仅限于 StoreCursor 类型的 Date 键)。

【问题讨论】:

  • 我猜它的抱怨是正确的,因为作为您的类型 T,您传递的是 StoreCursor,它不包含任何字符串类型的参数,而在您的 decode() 内部,第一个参数是字符串类型。所以你需要让你的泛型类型与你的函数 args 兼容。
  • 是的,但我试图引用 StoreCursorcreatedid)的键而不是它们的值。我也试过export interface TattooStoreCursor extends Record&lt;string, unknown&gt; { [...] },但错误是一样的。

标签: typescript


【解决方案1】:

JSON 回调的关键参数类型为string,而您的数组具有keyof T 类型的项目。 includes 需要与数组中的项具有相同类型的元素,并且无法在 TS 中表达类似 If it's a literal type or a key type, accept the base type (in this case string) 的内容。

您有以下两种选择之一:

首先断言 keykeyof T 可能不是,但这就是您正在测试的内容,因此断言不会出现运行时问题:

export default class PageUtil {
    public static decode<T>(cursor?: string, dates?: (keyof T)[]): T | undefined {
        if (!cursor) {
            return;
        }

        const json = "";

        return JSON.parse(json, (key, value) => (dates?.includes(key as keyof T) ? new Date(value) : value));
    }
}

Playground Link

或者另一种选择是使用单独的实现签名,其中dates 的类型为string[]

export default class PageUtil {
    public static decode<T>(cursor?: string, dates?: (keyof T)[]): T | undefined
    public static decode(cursor?: string, dates?: string[]): any {
        if (!cursor) {
            return;
        }

        const json = "";

        return JSON.parse(json, (key, value) => (dates?.includes(key) ? new Date(value) : value));
    }
}

Playground Link

【讨论】:

  • 我选择了第一个解决方案,似乎我更清楚。谢谢你。
猜你喜欢
  • 1970-01-01
  • 2018-12-17
  • 2022-08-02
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多