Как требовать, чтобы параметр был универсальным, строго расширяя частичное - PullRequest
0 голосов
/ 24 ноября 2018

Я пытаюсь достичь интуитивного результата, утверждая, что некоторый общий P является частичным O.

declare function foo<O, P extends Partial<O>>(obj: O, part: P): P

Однако, это позволяет ключам не O для P

// no errors
foo({a:2},{a:100, b:2})

Это

declare function foo<O, P>(obj: O, part: P & Partial<O>): P

также не работает * Эта версия работает

declare function foo<O, P>(obj: O, part: Partial<O>): unknown

// correct, Typescript complains that `b` is not allowed
foo({a:2},{a:100, b:2})

, однако тип возвращаемого значения не может использовать универсальный P.

Существует ли решение, ограничивающее P ключамив O и выполнены ли общие требования?

- Обновление

Для всех, кто интересуется, я опубликовал суть с некоторыми полезными частичными типами, которые не допускают избыточных свойств

https://gist.github.com/babakness/a1ca775f81097ffae04098a8cfdadc60

1 Ответ

0 голосов
/ 24 ноября 2018

Я не знаю, правильно ли я понимаю вариант использования, и не могу воспроизвести ваши результаты.Синтаксис function foo({a:2},{b:2}) не так, как вы вызываете функцию;если изменить это значение на foo({a:2},{b:2}), я получу проверку избыточного свойства с жалобой на свойство b.Всегда полезно убедиться, что вы предоставили Минимальный, завершенный и проверяемый пример , чтобы сосредоточить усилия ответчиков на решении проблемы, а не просто воспроизвести ее.

Все это времясказал, что если вам действительно нужно P, чтобы в нем были только ключи от O, вы можете получить это поведение (не уверенное в крайних случаях) со следующей сигнатурой:

declare function foo<O, P extends { [K in keyof P]: K extends keyof O ? O[K] : never }>(
  obj: O,
  part: P
): P;

Теперь Pограничивается типом, свойства которого должны совпадать со свойствами O, если они существуют в O, в противном случае они должны иметь тип never, что не может происходить с реальными значениями.Проверьте это:

const x = { b: 2 }
foo({ a: 2 }, x); // error, types of property 'b' are incompatible
foo({ b: 2 }, x); // okay
foo({ a: 2 }, {}); // okay

Хорошо выглядит.Надеюсь, это поможет;удачи!

...