如何改变一些对象属性而不出现Typescript错误?

eeq64g8w  于 2023-05-08  发布在  TypeScript
关注(0)|答案(2)|浏览(154)

这个问题与Zod无关,但我使用这个库来处理我的TS类型。
考虑下面的超简化模式:

export const Event = z
  .object({ 
    ... 
    subtype: z.array(z.enum(['abc', 'def', 'ghi']),
    ...
  })

export type Event = z.infer<typeof Event>

不管是什么原因,我想修改一个event对象如下:

export const stringify_event = (event: Event) => {
  event.subtype = event.subtype.join(',')    <-- Type 'string' is not assignable to type...
  return event
}

我不知道如何消除TS错误。如何“改变”我的事件?谢谢

--编辑--

我做了一个MRE来说明我的问题。
我想“改变”一个属性的原因是因为我使用了SQLite,它不允许array。所以在保存事件之前,我需要使它与SQLite兼容。

vmdwslir

vmdwslir1#

佐德在我的瞄准镜外。但是似乎你有一个z.union方法,你可以在你的Event对象中设置属性subtype: z.union([z.array(z.enum('abc'|'def'|'ghi')), z.string()]
我猜在typescript端属性子类型将被键入为[“abc”|“def”|“ghi”]|串,
带有属性Array<string> | string的MRE

ykejflvf

ykejflvf2#

我认为你不应该改变对象,而是创建一个新的对象,因为它们应该是不同的东西:

interface IEventSQL {
    a_key: number;
    another_key: string
}

const prepare_event_for_sqlite = (event: IEvent): IEventSQL => {
    return {
        a_key: event.a_key,
        another_key: event.another_key.join(',')
    }
}

另一方面,如果你把它们混合在一起(例如:将another_key定义为string[] | string),您将需要在所有地方使用类型保护,以确保它是string[]string,这很烦人
如果你想重用这个模式,一个实用程序类型会有帮助:

type ToSQL<T extends object> = {
    [K in keyof T]: T[K] extends any[] ? string : T[K]
}

type IEventSQL = ToSQL<IEvent>

类型ToSQL将所有Array属性转换为string,并保持不变。

相关问题