#typescript #typescript-typings
#typescript #typescript-типизации
Вопрос:
Рассмотрим следующий код…
Я бы ожидал, что оператор распространения будет допустимым кодом, но в конечном итоге это не так. Я надеюсь, что кто-нибудь, разбирающийся в Typescript, сможет посоветовать, почему это так…
export default function convertToGlobalFragment<
T extends basicFragmentRecipe_T
>(
fragmentFactory: (recipe: T) => configFragment_I,
recipe: T amp; { matchingRules: globalMatchingRules_T }
): globalConfigFragment_I {
let {
matchingRules,
...restOfRecipe
}: { matchingRules: globalMatchingRules_T, restOfRecipe: T } = recipe;
}
Код ошибки
Property 'restOfRecipe' is missing in type 'basicFragmentRecipe_T amp; { matchingRules: globalMatchingRules_T; }' but required in type '{ matchingRules: globalMatchingRules_T; restOfRecipe: T; }'.ts(2741)
Ответ №1:
recipe
является basicFragmentRecipe_T
плюсом { matchingRules: globalMatchingRules_T }
, и кажется, что basicFragmentRecipe_T
у restOfRecipe
него вообще нет prop.
Для назначения необходимо указать тот же целевой тип recipe
:
let {
matchingRules,
...restOfRecipe
}: { matchingRules: globalMatchingRules_T } amp; T = recipe;
Ответ №2:
let {
matchingRules,
...restOfRecipe
}: { matchingRules: globalMatchingRules_T, restOfRecipe: T } = recipe;
Эта часть неверна, потому что рецепт не содержит свойства, которое называется restOfRecipe
— it’s { matchingRules: globalMatchingRules_T } amp; T
— where T
, которое можно присвоить basicFragmentRecipe_T
Вы можете вытащить restOfRecipe без этого кода — пусть TS сделает всю работу:
let { matchingRules, ...restOfRecipe } = recipe;
Теперь restOfRecipe имеет тип:
Pick<T amp; { matchingRules: globalMatchingRules_T; }, Exclude<keyof T, "matchingRules">>
Давайте разберем это.
Тип рецепта — это комбинация T
и { matchingRules: globalMatchingRules_T; }
Чтобы получить из этого типа свойства, кроме ‘matchingRules’ — нам нужно исключить matchingRules из T
и { matchingRules: globalMatchingRules_T; }
. Поскольку последняя часть всегда будет содержать правила сопоставления, мы можем пропустить проверку комбинации и просто посмотреть Exclude<keyof T, "matchingRules"
, чтобы получить ключи T без «правил сопоставления».
Наконец, мы затем используем Pick<T, K>
для выбора ключей T
(без matchingRules
) из типа Recipe
, что дает нам результат выше.