Generi c Ограничение отображаемого типа с необязательным членом не ограничивает, когда один из членов существует - PullRequest
0 голосов
/ 04 мая 2020
const abc = <T extends object, P extends { [key in keyof T]?: number }>(
  a: T,
  b: P
) => {
  console.log(a, b);
};

const A = { x: "1", y: "2", z: "3" };
const b = { x: 1, y: 2, z: 3 };
const b1 = { x: 1, y: 2 };
const b3 = { m: 5 };
const b4 = { m: 5, x: 1 };

abc(A, b);
abc(A, b1);
abc(A, b3); // Type '{ m: number; }' has no properties in common with type '{ x?: number | undefined; y?: number | undefined; z?: number | undefined; }'
abc(A, b4); // expect type error just like b3 but it is not

, поскольку m не существует на A, b4 в случае ошибки, как b3, верно? но почему это не ошибка и как ее исправить?

вот песочница codesandbox

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Оказывается, это вообще не дженерики, это должен быть лучший способ представить мой вопрос:

const abc = <T extends { [index: string]: string }>(
  a: T,
  b: { [key in keyof T]?: number }
) => {
  console.log(a, b);
};

const A = { x: "1", y: "2", z: "3" };
const b4 = { m: 5, x: 1 };

abc(A, b4); // no error, not "expected"
abc(A, { m: 5, x: 1 }); // exact same value as b4 but throw error as "expected"

решение - вам нужно передать значение fre sh (значение, которое не является переменная)

для объяснения и другого решения (вспомогательный тип), прочитайте этот ответ и его комментарии

codesandbox для вопроса

обновление, я нашел идеальный вариант, так что

, поэтому решение будет таким:

const abc = <
  T extends { [index: string]: string },
  U extends { [key in keyof T]?: number }
>(
  a: T,
  b: keyof U extends keyof T ? U : never
) => {
  console.log(a, b);
};

const A = { x: "1", y: "2", z: "3" };
const b4 = { x: 1, y: 2, z: 3 };
const b5 = { m: 2, x: 5 };
const b6 = { x: 1, y: 2, z: 3, m: 2 };
const b7 = { x: 1 };

abc(A, b4); // no error, excat member
abc(A, b5); // error, excess member
abc(A, b6); // error, excess member
abc(A, b7); // no error, one of the member exist
abc(A, {}); // no error, since it is optional

// all work as expected

эта работа независимо от значения fre sh или не

решение codesandbox

0 голосов
/ 05 мая 2020

Тип '{м: число; } 'не имеет общих свойств с типом' {x ?: number | не определен; у ?: номер | не определен; z ?: число | не определен; }.

Ясно, что b4 не ошибка, потому что имеет один из x ?, y? г? включен. это потому, что вы выходите из T, а T - из первого передаваемого вами параметра: A.

...