访问代理对象时出现 TypeScript 错误 | MobX 中的对象[]
TypeScript error while accessing Proxy Object | Object[] in MobX
我有一个简单的 MobX 商店:
import { observable, action, makeObservable } from "mobx"
import { BoxShadow, ShadowValues } from "./types"
import { boxShadow } from "./constants"
interface IStore {
shadow: BoxShadow
}
export class Store implements IStore {
shadow: BoxShadow = {
selected: "DEFAULT",
list: boxShadow,
}
constructor() {
makeObservable(this, {
shadow: observable,
updateShadow: action.bound,
})
}
updateShadow(selected: ShadowValues) {
this.shadow.selected = selected
}
}
export const store = new Store()
BoxShadow
& ShadowValues
类型包括:
type Point = {
x: number
y: number
}
export type ShadowValues =
| "none"
| "sm"
| "DEFAULT"
| "md"
| "lg"
| "xl"
| "2xl"
| "3xl"
export type Shadow = {
offset: Point
blur: number
shadow: number
color: string
}
export type ShadowList = Record<ShadowValues, Shadow[] | Shadow>
export type BoxShadow = {
selected: ShadowValues
list: ShadowList
}
我正在使用 HTML select 并更新 boxShadow
值:
import * as React from "react"
import { toJS } from "mobx"
import { observer } from "mobx-react"
import { useStore } from "./context"
import { Select } from "./Select"
import { shadows } from "./constants"
import { ShadowValues } from "./types"
export default observer(function App() {
const { shadow, updateShadow } = useStore()
console.log(toJS(shadow.list[shadow.selected])[0]["offset"])
console.log(shadow.list[shadow.selected].offset)
return (
<div className="w-full flex flex-col items-center">
<h1 className="text-4xl">Access MobX Proxy</h1>
<Select
className="flex-1 w-56"
label="Box Shadow"
checkmark={true}
options={shadows}
selectedOption={
shadows.filter(({ value }) => value === shadow.selected)[0]
}
onChange={(selectedOption) => {
const selected = selectedOption.value as ShadowValues
updateShadow(selected)
}}
/>
</div>
)
})
但是,如果没有 TypeScript 对我大喊大叫,我无法访问 selectedShadow.color
或 selectedShadow.offset
。
boxShadow
值由一个对象或对象数组组成,例如:
export const boxShadow = {
none: {
offset: { x: 0, y: 0 },
blur: 0,
shadow: 0,
color: "rgba(0, 0, 0, 0)",
},
sm: {
offset: { x: 0, y: 1 },
blur: 2,
shadow: 0,
color: "rgba(0, 0, 0, 0.05)",
},
DEFAULT: [
{
offset: { x: 0, y: 1 },
blur: 3,
shadow: 0,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 1 },
blur: 2,
shadow: 0,
color: "rgba(0, 0, 0, 0.06)",
},
],
md: [
{
offset: { x: 0, y: 4 },
blur: 6,
shadow: -1,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 2 },
blur: 4,
shadow: -1,
color: "rgba(0, 0, 0, 0.06)",
},
],
lg: [
{
offset: { x: 0, y: 10 },
blur: 15,
shadow: -3,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 4 },
blur: 6,
shadow: -2,
color: "rgba(0, 0, 0, 0.05)",
},
],
xl: [
{
offset: { x: 0, y: 20 },
blur: 25,
shadow: -5,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 10 },
blur: 10,
shadow: -5,
color: "rgba(0, 0, 0, 0.04)",
},
],
"2xl": {
offset: { x: 0, y: 25 },
blur: 50,
shadow: -12,
color: "rgba(0, 0, 0, 0.25)",
},
"3xl": {
offset: { x: 0, y: 35 },
blur: 60,
shadow: -15,
color: "rgba(0, 0, 0, 0.3)",
},
}
我正在尝试使用 toJS
访问它,但仍然无法访问嵌套属性。但是,如果我 console.log
它 .toJS
方法显示得很好:
import * as React from "react"
import { toJS } from "mobx"
import { observer } from "mobx-react"
import { useStore } from "./context"
import { Select } from "./Select"
import { shadows } from "./constants"
import { ShadowValues } from "./types"
export default observer(function App() {
const { shadow, updateShadow } = useStore()
console.log(toJS(shadow.list[shadow.selected])[0]["offset"])
console.log(shadow.list[shadow.selected].offset)
return (
<div className="w-full flex flex-col items-center">
<h1 className="text-4xl">Access MobX Proxy</h1>
<Select
className="flex-1 w-56"
label="Box Shadow"
checkmark={true}
options={shadows}
selectedOption={
shadows.filter(({ value }) => value === shadow.selected)[0]
}
onChange={(selectedOption) => {
const selected = selectedOption.value as ShadowValues
updateShadow(selected)
}}
/>
</div>
)
})
查看上面的 console.log
。我想以某种方式访问这些值。
如果我这样做 shadow.list[shadow.selected][0].color
,我得到:
TS7053: Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'string | Shadow[] | Shadow'.
Property '0' does not exist on type 'string | Shadow[] | Shadow'.
如果我这样做 shadow.list[shadow.selected].color
,我得到:
TS2339: Property 'color' does not exist on type 'string | Shadow[] | Shadow'.
Property 'color' does not exist on type 'string'.
哪个是正确的,但我不知道如何解决:(
我做了a minimal Codesandbox看demo。请注意,它有时 console.log
在 Codesandbox 上但不在本地,但它确实也会在 Codesandbox 上给出 TS 错误。
我该如何解决这个问题?我也想访问对象值 sm.offset
加上对象数组 DEFAULT[0].offset
& DEFAULT[1].offset
:)
因为我的类型是Shadow | Shadow[]
,所以当我必须访问它时,我不得不添加一个守卫来缩小类型。所以我做了以下让它工作:
if (Array.isArray(selected)) {
console.log(selected[0].offset);
} else {
console.log(selected.offset);
}
我尝试了 typeof selected
并且它一直给我 object
我忘记了 JS 认为一切都是 object
所以从来没有尝试过上面的东西:)
我有一个简单的 MobX 商店:
import { observable, action, makeObservable } from "mobx"
import { BoxShadow, ShadowValues } from "./types"
import { boxShadow } from "./constants"
interface IStore {
shadow: BoxShadow
}
export class Store implements IStore {
shadow: BoxShadow = {
selected: "DEFAULT",
list: boxShadow,
}
constructor() {
makeObservable(this, {
shadow: observable,
updateShadow: action.bound,
})
}
updateShadow(selected: ShadowValues) {
this.shadow.selected = selected
}
}
export const store = new Store()
BoxShadow
& ShadowValues
类型包括:
type Point = {
x: number
y: number
}
export type ShadowValues =
| "none"
| "sm"
| "DEFAULT"
| "md"
| "lg"
| "xl"
| "2xl"
| "3xl"
export type Shadow = {
offset: Point
blur: number
shadow: number
color: string
}
export type ShadowList = Record<ShadowValues, Shadow[] | Shadow>
export type BoxShadow = {
selected: ShadowValues
list: ShadowList
}
我正在使用 HTML select 并更新 boxShadow
值:
import * as React from "react"
import { toJS } from "mobx"
import { observer } from "mobx-react"
import { useStore } from "./context"
import { Select } from "./Select"
import { shadows } from "./constants"
import { ShadowValues } from "./types"
export default observer(function App() {
const { shadow, updateShadow } = useStore()
console.log(toJS(shadow.list[shadow.selected])[0]["offset"])
console.log(shadow.list[shadow.selected].offset)
return (
<div className="w-full flex flex-col items-center">
<h1 className="text-4xl">Access MobX Proxy</h1>
<Select
className="flex-1 w-56"
label="Box Shadow"
checkmark={true}
options={shadows}
selectedOption={
shadows.filter(({ value }) => value === shadow.selected)[0]
}
onChange={(selectedOption) => {
const selected = selectedOption.value as ShadowValues
updateShadow(selected)
}}
/>
</div>
)
})
但是,如果没有 TypeScript 对我大喊大叫,我无法访问 selectedShadow.color
或 selectedShadow.offset
。
boxShadow
值由一个对象或对象数组组成,例如:
export const boxShadow = {
none: {
offset: { x: 0, y: 0 },
blur: 0,
shadow: 0,
color: "rgba(0, 0, 0, 0)",
},
sm: {
offset: { x: 0, y: 1 },
blur: 2,
shadow: 0,
color: "rgba(0, 0, 0, 0.05)",
},
DEFAULT: [
{
offset: { x: 0, y: 1 },
blur: 3,
shadow: 0,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 1 },
blur: 2,
shadow: 0,
color: "rgba(0, 0, 0, 0.06)",
},
],
md: [
{
offset: { x: 0, y: 4 },
blur: 6,
shadow: -1,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 2 },
blur: 4,
shadow: -1,
color: "rgba(0, 0, 0, 0.06)",
},
],
lg: [
{
offset: { x: 0, y: 10 },
blur: 15,
shadow: -3,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 4 },
blur: 6,
shadow: -2,
color: "rgba(0, 0, 0, 0.05)",
},
],
xl: [
{
offset: { x: 0, y: 20 },
blur: 25,
shadow: -5,
color: "rgba(0, 0, 0, 0.1)",
},
{
offset: { x: 0, y: 10 },
blur: 10,
shadow: -5,
color: "rgba(0, 0, 0, 0.04)",
},
],
"2xl": {
offset: { x: 0, y: 25 },
blur: 50,
shadow: -12,
color: "rgba(0, 0, 0, 0.25)",
},
"3xl": {
offset: { x: 0, y: 35 },
blur: 60,
shadow: -15,
color: "rgba(0, 0, 0, 0.3)",
},
}
我正在尝试使用 toJS
访问它,但仍然无法访问嵌套属性。但是,如果我 console.log
它 .toJS
方法显示得很好:
import * as React from "react"
import { toJS } from "mobx"
import { observer } from "mobx-react"
import { useStore } from "./context"
import { Select } from "./Select"
import { shadows } from "./constants"
import { ShadowValues } from "./types"
export default observer(function App() {
const { shadow, updateShadow } = useStore()
console.log(toJS(shadow.list[shadow.selected])[0]["offset"])
console.log(shadow.list[shadow.selected].offset)
return (
<div className="w-full flex flex-col items-center">
<h1 className="text-4xl">Access MobX Proxy</h1>
<Select
className="flex-1 w-56"
label="Box Shadow"
checkmark={true}
options={shadows}
selectedOption={
shadows.filter(({ value }) => value === shadow.selected)[0]
}
onChange={(selectedOption) => {
const selected = selectedOption.value as ShadowValues
updateShadow(selected)
}}
/>
</div>
)
})
查看上面的 console.log
。我想以某种方式访问这些值。
如果我这样做 shadow.list[shadow.selected][0].color
,我得到:
TS7053: Element implicitly has an 'any' type because expression of type '0' can't be used to index type 'string | Shadow[] | Shadow'. Property '0' does not exist on type 'string | Shadow[] | Shadow'.
如果我这样做 shadow.list[shadow.selected].color
,我得到:
TS2339: Property 'color' does not exist on type 'string | Shadow[] | Shadow'. Property 'color' does not exist on type 'string'.
哪个是正确的,但我不知道如何解决:(
我做了a minimal Codesandbox看demo。请注意,它有时 console.log
在 Codesandbox 上但不在本地,但它确实也会在 Codesandbox 上给出 TS 错误。
我该如何解决这个问题?我也想访问对象值 sm.offset
加上对象数组 DEFAULT[0].offset
& DEFAULT[1].offset
:)
因为我的类型是Shadow | Shadow[]
,所以当我必须访问它时,我不得不添加一个守卫来缩小类型。所以我做了以下让它工作:
if (Array.isArray(selected)) {
console.log(selected[0].offset);
} else {
console.log(selected.offset);
}
我尝试了 typeof selected
并且它一直给我 object
我忘记了 JS 认为一切都是 object
所以从来没有尝试过上面的东西:)