首页 > 解决方案 > 根据用作返回的接口限制数组值

问题描述

我有这个代码:

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:“字符串”类型的参数不可分配给“keyof T & string”类型的参数。类型“字符串”不可分配给类型“keyof T”。

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

标签: typescript

解决方案


回调的关键参数JSON类型为string,而您的数组具有类型的项目keyof Tincludes期望与数组中的项目具有相同类型的元素,并且无法在 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));
    }
}

游乐场链接

或者另一种选择是使用单独的实现签名,其中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));
    }
}

游乐场链接


推荐阅读