首页 > 解决方案 > 如何正确键入接收具有多个键:值对的对象的函数?

问题描述

我有一个对象,其中包含一些用户会话值:

const userSession = {
  token: '',
  full_name: '',
  username: '',
  password: '',
  role_name: '',
  gender: '',
}

我有一个函数必须更新这个对象中的一个或多个值,但我很难指定具有未知数量值的对象类型。感觉必须用泛型来完成,但我对它们没有太多经验。例如,如果调用

updateSession({token: 'some new token value', gender: 'new gender'})
should return {
  token: 'some new token value',
  full_name: '',
  username: '',
  password: '',
  role_name: '',
  gender: 'new gender',
}

我试过的:

const updateSession = <T extends {}>(objectParam: T) => {
  const updatedUserObject = { ...userSession }
  for (const [key, value] of Object.entries(objectParam)) {
    console.log(`${key} ${value}`)
    updatedUserObject[key] = value
  }
  return updatedUserObject
}

但这根本没有多大意义……

现在使用@obe 的解决方案可以让我Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'UserSessionInterface'. No index signature with a parameter of type 'string' was found on type 'UserSessionInterface' 知道我的功能和界面在哪里:

export interface UserSessionInterface {
  token: string
  email?: string
  full_name?: string
  username?: string
  password?: string
  role_name?: string
  gender?: string
  imageUri?: string
}

const session: UserSessionInterface = {
  token: '',
  full_name: '',
  username: '',
  password: '',
  role_name: '',
  gender: '',
}

const updateSession = (objectWithUpdates: UserSessionInterface) => {
      const updatedUserObject: UserSessionInterface = { ...session }
      for (const [key, value] of Object.entries(objectWithUpdates)) {
        console.log(`${key} ${value}`)
        updatedUserObject[key] = value
      }
      try {
        await EncryptedStorage.setItem(
          'user_session',
          JSON.stringify(updatedUserObject),
        )
        console.log('successfully updated data')
        console.log(updatedUserObject)
        setSession(updatedUserObject)
      } catch (error) {
        console.error(error)
      }
    }

我已经修复了updatedUserObject[key as keyof IEmptySession] = value,所以我现在想知道,这是一个有效的修复还是有更好的方法?出现该错误的TSPlayground

标签: typescript

解决方案


您可以将对象声明为带有(一些?)可选键的接口:

interface IEmptySession {
  token: string,
  full_name?: string,
  username?: string,
  password?: string,
  role_name?: string,
  gender: string,
}

...

const updateSession = (objectParam: IEmptySession): IEmptySession => {
  const updatedUserObject: IEmptySession = { ...objectParam }
  for (const [key, value] of Object.entries(objectParam)) {
    console.log(`${key} ${value}`)
    updatedUserObject[key] = value
  }
  return updatedUserObject
}

如果您想允许任何键,那么您可以像这样定义接口:

interface IEmptySession {
   [index: string]: string;
}

推荐阅读