微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

访问代理对象时出现 TypeScript 错误 | MobX 中的 Object[]

如何解决访问代理对象时出现 TypeScript 错误 | MobX 中的 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()

BoxShadowShadowValues 类型包括

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 选择并更新 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.colorselectedShadow.offset

BoxShadow 值由一个对象或一组对象组成,例如:

export const BoxShadow = {
    none: {
        offset: { x: 0,y: 0 },blur: 0,shadow: 0,color: "rgba(0,0)",},sm: {
        offset: { x: 0,y: 1 },blur: 2,0.05)",DEFAULT: [
        {
            offset: { x: 0,blur: 3,0.1)",{
            offset: { x: 0,0.06)",],md: [
        {
            offset: { x: 0,y: 4 },blur: 6,shadow: -1,y: 2 },blur: 4,lg: [
        {
            offset: { x: 0,y: 10 },blur: 15,shadow: -3,shadow: -2,xl: [
        {
            offset: { x: 0,y: 20 },blur: 25,shadow: -5,blur: 10,0.04)","2xl": {
        offset: { x: 0,y: 25 },blur: 50,shadow: -12,0.25)","3xl": {
        offset: { x: 0,y: 35 },blur: 60,shadow: -15,0.3)",}

我正在尝试使用 toJS 访问它,但仍然无法访问嵌套属性.toJS 方法但是如果我 console.log显示完美:

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:元素隐式具有“any”类型,因为类型“0”的表达式不能用于索引类型“string |”阴影[] |阴影'。 类型 'string | 中不存在属性 '0'阴影[] |阴影'。

如果我执行 shadow.list[shadow.selected].color,我会得到:

TS2339:类型“字符串”上不存在属性“颜色”|阴影[] |阴影'。 'string' 类型不存在属性 'color'。

这是正确的,但我不知道如何解决它:(

我已经制作了 a minimal Codesandbox 来观看演示。请注意,它有时 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 所以从来没有尝试过上面的东西 :)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。