网站搜索

Typescript - 目标需要 2 个元素,但源可能有更少


我有一个函数正在推断类型,但是当我模拟这个函数的响应时,它会报错。

  1. 类型为 '({ id: string; authentication_id: string; dtype: string; session: string; }[] | null)[]' 的参数不能赋值给类型 'readonly [null, any] | readonly [IFindUserWithAuthResponse[], null] | Promise' 的参数。类型 '({ id: string; authentication_id: string; dtype: string; session: string; }[] | null)[]' 不能赋值给类型 'readonly [IFindUserWithAuthResponse[], null]'。目标需要 2 个元素,但来源可能少于 2 个。
   const mockFindUserWithAuthData = [
            [
                {
                    id: "123",
                    authentication_id: "123",
                    dtype: "checkpoint_login",
                    session: "123",
                },
            ],
            null,
        ];

onst mockFindUserWithAuth = jest.mocked(FindUserWithAuth);

mockFindUserWithAuth.mockResolvedValueOnce(mockFindUserWithAuthData); // ts error here

函数

我在这里使用 as const,这样我就不必手动写返回类型了。

const FindUserWithAuth: (auth_id: string) => Promise<readonly [IFindUserWithAuthResponse[], null] | readonly [null, any]>
interface IFindUserWithAuthResponse extends RowDataPacket {
    id: string;
    authentication_id: string;
    dtype: string;
    session: string;
}

export const FindUserWithAuth = async (auth_id: string) => {
    const query = `        
        SELECT u.*, a.id as authentication_id, a.dtype, a.session
        FROM user u
        JOIN authentication a on u.id = a.user_id
        WHERE a.id = ?
        AND a.deleted_at IS NULL
    `;

    const q = MySQLPreparedStatement(query, [auth_id]);
    try {
        const [rows, field] = await MySQLMaster.query<IFindUserWithAuthResponse[]>(q);
        return [rows, null] as const;
    } catch (err) {
        Logger.error({ method: "FindUserWithAuth", error: err, stack_trace: err.stack });
        return [null, err] as const;
    }
};

答案#1

这未经测试,但如果你在数据中添加 as const,它应该可以工作:

   const mockFindUserWithAuthData = [
            [
                {
                    id: "123",
                    authentication_id: "123",
                    dtype: "checkpoint_login",
                    session: "123",
                },
            ],
            null,
        ] as const;

默认情况下,类似这样的东西:

const a = [1, "4"];

将被写作 (string | number)[],即一个任意长度的数组,其项是字符串或数字。

另一方面,这个:

const a = [1, "4"] as const;

告诉编译器这是一个包含两个元素的元组,第一个元素是数字,第二个元素是字符串(实际上第一个元素明确为 1,第二个元素为“4”)。