#typescript
#typescript
Вопрос:
Я хочу, чтобы typescript утверждал, что «новая» строка не является частью объединения, существующего набора, в который будет добавлена строка.
Я ищу независимую, отдельную строку кода, но это просто приятно иметь.
Итак, простая, хотя и надуманная ситуация:
type FruitOptions = 'banana' | 'apple' | 'grape'
type NewFruitOption = 'pear'
// ^ being passed into a function ^
// Assert: FruitOptions does not contain NewFruitOption
Я не думаю, что совместное использование этого необходимо, но это служебная функция, в которой я пытаюсь использовать эту технику:
// These are inferred generics (since they come after the = sign), do not pass them in.
export const renameKey = <
OldKey extends keyof T,
NewKey extends string, // should NOT already be keyof T
T extends Record<string, unknown>
>(
oldKey: OldKey,
newKey: NewKey,
userObject: T
): Record<NewKey, T[OldKey]> amp; Omit<T, OldKey> => {
const { [oldKey]: value, ...common } = userObject
return {
...common,
...({ [newKey]: value } as Record<NewKey, T[OldKey]>)
}
}
Ответ №1:
Вы можете проверить, NewKey
расширяется keyof T
ли значение, и если это так, задайте для параметра type never
значение, чтобы typescript выдал ошибку:
newKey: NewKey extends keyof T ? never : NewKey
Когда вы затем измените этот допустимый вызов:
renameKey('lastName', 'clientLastName', formData)
Быть недействительным:
renameKey('lastName', 'lastName', formData)
Вы получите красное подчеркивание на втором 'lastName'
высказывании: Argument of type 'string' is not assignable to parameter of type 'never'. ts(2345)
. Также произойдет сбой, если вы попытаетесь переименовать ключ в любой другой ключ, который уже существует:
renameKey('lastName', 'dateOfBirth', formData)