Typescript 类型脚本:断言字符串不是联合的一部分

Typescript 类型脚本:断言字符串不是联合的一部分,typescript,Typescript,我想让typescript断言“新”字符串不是联合的一部分,而是字符串将添加到的现有集合 我正在寻找一个独立的代码行,但这只是一个很好的选择 因此,简单但人为的情况是: type FruitOptions = 'banana' | 'apple' | 'grape' type NewFruitOption = 'pear' // ^ being passed into a function ^ // Assert: FruitOptions does not contain NewFruitO

我想让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]> & Omit<T, OldKey> => {
  const { [oldKey]: value, ...common } = userObject

  return {
    ...common,
    ...({ [newKey]: value } as Record<NewKey, T[OldKey]>)
  }
}
//这些是推断的泛型(因为它们位于=号之后),不要传入它们。
导出常量重命名键=<
OldKey扩展了Keyt,
NewKey扩展字符串,//不应该是keyof T
T延续记录
>(
oldKey:oldKey,
纽基:纽基,
用户对象:T
):记录并忽略=>{
常量{[oldKey]:值,…公共}=userObject
返回{
…普通,
…({[newKey]:值}作为记录)
}
}

您可以检查
NewKey
是否扩展了
keyof T
,如果扩展了,请将参数类型设置为
never
,这样类型脚本将出错:

newKey: NewKey extends keyof T ? never : NewKey
然后更改此有效呼叫时:

renameKey('lastName', 'clientLastName', formData)
无效:

renameKey('lastName', 'lastName', formData)
第二个
'lastName'
上会有一条红色下划线,上面写着:
类型为'string'的参数不能分配给类型为'never'的参数。ts(2345)
。如果尝试将该密钥重命名为任何其他已存在的密钥,也会失败:

renameKey('lastName', 'dateOfBirth', formData)