传播价值未在创建方法中识别

发布于 2025-01-26 21:06:18 字数 1619 浏览 3 评论 0原文

Deno在全球范围内可用,这是我用作内存数据库的方法。

我正在研究一种在Sessionstorage中创建新博物馆的方法。但是,问题是我的创建方法仅在我的博物馆类型不扩展记录时起作用。

这是我的类型:

// I want my Museum type to extend the Record type for the extra type safety
interface Museum extends Record<string, unknown> {
  id: string
  name: string
  description: string
  location: {
    lat: number
    lng: number
  }
  createdAt: Date
  updatedAt?: Date
}

// I'm testing two different NewMuseum types
type NewMuseum = Omit<Museum, "id" | "createdAt" | "updatedAt">
// type NewMuseum = Partial<Museum>

这是我的班级:

export class Repository {
  
  async getList(): Promise<Museum[]> {
    return JSON.parse(sessionStorage.getItem('museums') || '[]') as Museum[]
  }

  async create(museum: NewMuseum): Promise<Museum> {
    const museumList = await this.getList()
    const newMuseum = {
      id: crypto.randomUUID(),
      ...museum,
      createdAt: new Date(),
    }
    museumList.push(newMuseum)
    sessionStorage.setItem('museums', JSON.stringify(museumList))
    
    return newMuseum
  }
}

当我去传播新博物馆的价值时,林格在newmuseum上遇到了一个错误,线。

Argument of type '{ createdAt: Date; id: string; }' is not assignable to parameter of type 'Museum'.deno-ts(2345)

Newmuseum并未认识到我在其中散布的价值。相反,NewMuseum应该看起来像这样:

const newMuseum: {
    createdAt: Date;
    name: string;
    description: string;
    location: {
        lat: number;
        lng: number;
    };
    id: string;
}

如何获得NewMuseum来识别差异值?我是否应该尝试使用部分效用类型而不是省略来解决问题?

Deno has sessionStorage globally available, which is what I'm using as my in-memory database.

I'm working on a method that creates a new museum in sessionStorage. However, the problem is that my create method only works when my Museum type does not extend Record.

Here are my types:

// I want my Museum type to extend the Record type for the extra type safety
interface Museum extends Record<string, unknown> {
  id: string
  name: string
  description: string
  location: {
    lat: number
    lng: number
  }
  createdAt: Date
  updatedAt?: Date
}

// I'm testing two different NewMuseum types
type NewMuseum = Omit<Museum, "id" | "createdAt" | "updatedAt">
// type NewMuseum = Partial<Museum>

Here is my class:

export class Repository {
  
  async getList(): Promise<Museum[]> {
    return JSON.parse(sessionStorage.getItem('museums') || '[]') as Museum[]
  }

  async create(museum: NewMuseum): Promise<Museum> {
    const museumList = await this.getList()
    const newMuseum = {
      id: crypto.randomUUID(),
      ...museum,
      createdAt: new Date(),
    }
    museumList.push(newMuseum)
    sessionStorage.setItem('museums', JSON.stringify(museumList))
    
    return newMuseum
  }
}

When I go to spread the values of the new museum the linter catches an error on newMuseum on the museumList.push(newMuseum) line.

Argument of type '{ createdAt: Date; id: string; }' is not assignable to parameter of type 'Museum'.deno-ts(2345)

newMuseum isn't recognizing the values I'm spreading in it. Instead, newMuseum should look like this:

const newMuseum: {
    createdAt: Date;
    name: string;
    description: string;
    location: {
        lat: number;
        lng: number;
    };
    id: string;
}

How do I get newMuseum to recognize the spread values? Should I be attempting to fix the issue with the Partial utility type instead of Omit?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱你不解释 2025-02-02 21:06:18

将Newmuseum物体铸造为博物馆是什么诀窍。这是更新的解决方案:

export class Repository {
  
  async getList(): Promise<Museum[]> {
    return JSON.parse(sessionStorage.getItem('museums') || '[]') as Museum[]
  }

  async create(museum: NewMuseum): Promise<Museum> {
    const museumList = await this.getList()
    const newMuseum = {
      ...museum,
      id: crypto.randomUUID(),
      createdAt: new Date(),
    } as Museum
    museumList.push(newMuseum)
    sessionStorage.setItem('museums', JSON.stringify(museumList))
    
    return newMuseum
  }
}

Typescript并不真正知道传播操作员的类型,因此假设它不兼容。正如博物馆告诉Typescript Typechecker“不用担心,我敢肯定这是对的。”

向Deno Discord喊叫!

Casting the newMuseum object as Museum is what did the trick. Here is the updated solution:

export class Repository {
  
  async getList(): Promise<Museum[]> {
    return JSON.parse(sessionStorage.getItem('museums') || '[]') as Museum[]
  }

  async create(museum: NewMuseum): Promise<Museum> {
    const museumList = await this.getList()
    const newMuseum = {
      ...museum,
      id: crypto.randomUUID(),
      createdAt: new Date(),
    } as Museum
    museumList.push(newMuseum)
    sessionStorage.setItem('museums', JSON.stringify(museumList))
    
    return newMuseum
  }
}

Typescript doesn't really know the type of the spread operator so it assumes it's incompatible. as Museum tells the typescript typechecker "no worries, I'm sure this is right."

Shoutout to the Deno Discord for the help!

沫雨熙 2025-02-02 21:06:18

由于newmuseum不包含它们,因此不存在您期望在差异操作中识别的值。 省略正在导致更改的密钥集:

type NewMuseum = Omit<Museum, "id" | "createdAt" | "updatedAt">;

会这样做

type NewMuseum = {
    [x: string]: unknown;
    [x: number]: unknown;
}

interface NewMuseum extends Record<string, unknown> {
  name: string;
  description: string;
  location: {
    lat: number;
    lng: number;
  };
}

在您尝试传播newmuseum这些密钥的类型信息已经丢失之前,就不 。

您可以考虑通过省略来构成类型而不是计算类型。

例如

type MuseumData = Record<string, unknown> & {
  name: string;
  description: string;
  location: {
    lat: number;
    lng: number;
  };
};

type MuseumMetadata = {
  id: string;
  createdAt: Date;
  updatedAt?: Date;
};

type Museum = MuseumData & MuseumMetadata;

type NewMuseum = MuseumData;

The values you are expecting to be recognized in your spread operation are not there because the NewMuseum doesn't contain them. Omit is causing the set of keys to be changed:

type NewMuseum = Omit<Museum, "id" | "createdAt" | "updatedAt">;

resolves to

type NewMuseum = {
    [x: string]: unknown;
    [x: number]: unknown;
}

and not to

interface NewMuseum extends Record<string, unknown> {
  name: string;
  description: string;
  location: {
    lat: number;
    lng: number;
  };
}

As such, long before you attempt to spread a NewMuseum the type information for those keys is already lost.

You might consider composing your types rather computing types via utilities like Omit.

e.g.

type MuseumData = Record<string, unknown> & {
  name: string;
  description: string;
  location: {
    lat: number;
    lng: number;
  };
};

type MuseumMetadata = {
  id: string;
  createdAt: Date;
  updatedAt?: Date;
};

type Museum = MuseumData & MuseumMetadata;

type NewMuseum = MuseumData;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文