当使用Pinia和TypeScript时,如何使用Action来设置State



我有一个名为user.ts的Pinia+TypeScript存储,看起来像这样:

import { User } from 'firebase/auth';
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
state: () =>
({
displayName: null,
email: null,
emailVerified: null,
isAnonymous: null,
metadata: null,
multiFactor: null,
phoneNumber: null,
photoURL: null,
providerData: null,
providerId: null,
refreshToken: null,
tenantId: null,
uid: null,
} as unknown as User),
actions: {
setPhotoURL(photoURLData: string | null) {
this.photoURL = photoURLData; //<-- ERROR HERE
},
},
});

状态是FireBase User对象。

我想使用setPhotoURL()操作来更新photoURL

但是photoURL有这个TypeScript错误:

Cannot assign to 'photoURL' because it is a read-only property. ts(2540)

我做错了什么?

这是更新状态的正确方式吗?

您可以通过映射类型来移除readonly修饰符:

映射修改器

映射过程中可以应用两个额外的修饰符:readonly?,它们分别影响可变性和可选性。

您可以通过前缀-+来删除或添加这些修饰符。如果不添加前缀,则假定为+

// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};

如果类型具有您希望可写的嵌套属性,则递归映射:

type CreateMutable<T> = { -readonly [P in keyof T]: CreateMutable<T[P]> }

然后使用它键入商店的user属性:

import type { User } from 'firebase/auth'
import { defineStore } from 'pinia'
type CreateMutable<T> = { -readonly [P in keyof T]: CreateMutable<T[P]> }
export const useUserStore = defineStore('user', {
state: () => ({ user: {} as CreateMutable<User> }),
actions: {
setPhotoURL(photoURLData: string | null) {
this.user.photoURL = photoURLData
},
},
})

'firebase/auth'声明用户界面具有readonly道具。当您将该接口强制应用于状态对象时,TS信任您。

传播它应该会从道具中移除readonly,同时仍然推断类型:

export const useUserStore = defineStore('user', {
state: () => ({ ...({
displayName: null,
email: null,
emailVerified: null,
isAnonymous: null,
metadata: null,
multiFactor: null,
phoneNumber: null,
photoURL: null,
providerData: null,
providerId: null,
refreshToken: null,
tenantId: null,
uid: null,
} as unknown as User) }),
actions: {
//...
}
})

最新更新