运行时API和Typedefs:由于类型定义,是否有可能过滤数据?

发布于 2025-02-09 22:19:43 字数 1586 浏览 1 评论 0原文

我的假设是:应该可以从运行时存在的Typedef创建某种防护措施。我想我在某个地方阅读了TS4+。

有可能

实际上是两个问题,其中一个应该可以解决:

  1. 如果您的API(无法控制)给您嘈杂的数据,并且由于现有的类型定义,如何,您正在尝试过滤它们你会去吗?

  2. 有时,您的类型定义看起来很奇怪,并且您不能轻松地通过lodash.keyby过滤,因为ITEMERETERE可以根据给定的Typedefs具有不同的形状。

示例:

您具有这样的对象类型:

type ObjectType = {
  [key: string]: {
    foo?: string | number;
  };
};

由于Objecttype上面的遵循数据将通过:

const someOKCollection: Array<ObjectType> = [
  { june: { foo: 1 } },
  { earth: {} },
  { milky: { foo: "Hi" } }
];

想象一下,这来自API:

const collectionFromApi: Array<unknown> = [
  { car: { foo: 1 } },
  { soup: {} },
  { water: { foo: "Hi" } },
  { sun: { bar: "Hi" } }
];

在这种情况下,sun由于Objecttype而不必要(因为它具有bar)。令人兴奋的点是,我需要以下形式的数据:

const desiredResult = {
  noMatter: { foo: 1 },
  what: {},
  Ever: { foo: "Hi" }
};

最终问题:

不管第一个问题是否可以解决,如何从TypeDeDefiniton中形成(自动)iteratee这样我使用lodash.keyby或其他一些收集功能并获得所需的目标?

编辑:在这里简化的代码和一个简化的代码: https://codesandbox.io/s/typescript-lodash-types-6844w0?file=/src/index.type.ts 请注意: root> root键键名称可以与运行时的A,B,C不同,只有键入键入)必须尊重)

My assumption: It should be possible to create some kind of guard from TypeDefs that will exist at runtime. I imagine that I read somewhere that it is somehow possible with TS4+.

Actually two Questions, one of them should be solvable:

  1. If, e.g. your API (out of your control) gives you noisy data and you are trying to filter them due to existing type definitions, how would you go?

  2. Sometimes, your type definitions can look weird, and you cannot easily filter by lodash.keyBy because the iteratee can have different shapes depending on the given TypeDefs.

Example:

You have an object type like this:

type ObjectType = {
  [key: string]: {
    foo?: string | number;
  };
};

Following data would pass due to the ObjectType above:

const someOKCollection: Array<ObjectType> = [
  { june: { foo: 1 } },
  { earth: {} },
  { milky: { foo: "Hi" } }
];

Imagine, that is coming from an API:

const collectionFromApi: Array<unknown> = [
  { car: { foo: 1 } },
  { soup: {} },
  { water: { foo: "Hi" } },
  { sun: { bar: "Hi" } }
];

In this case sun is unnecessary due to the ObjectType (because it has bar). And the exciting point is I need the data in form of:

const desiredResult = {
  noMatter: { foo: 1 },
  what: {},
  Ever: { foo: "Hi" }
};

Final Question:

Regardless of whether the first question is solvable, how should the iteratee be formed (automatically) from TypeDefiniton so that I use lodash.keyBy or some other collection function and get the desired goal?

EDIT: A simplified CodeSandBox here: https://codesandbox.io/s/typescript-lodash-types-6844w0?file=/src/index.type.ts (please notice: root key names can be different than a,b,c in runtime, only TypeDefs have to be respected)

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

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

发布评论

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

评论(1

两个我 2025-02-16 22:19:43

没有lodash:

https:/// codesandbox.io/s/typescript-lodash-types-forked-11io7p?file=/src/index.type.ts

// import keyBy from "lodash/fp/keyBy";

type ObjectType = {
  [key: string]: {
    foo?: string | number;
  };
};

// const someOKCollection: Array<ObjectType> = [
//   { a: { foo: 1 } },
//   { b: {} },
//   { c: { foo: "Hi" } }
// ];

const collectionFromApi: unknown[] = [
  { a: { foo: 1 } },
  { b: {} },
  { c: { foo: "Hi" } },
  { d: { bar: "Hi" } }
];

type AllowedKey = "a" | "b" | "c";
const allowedKeys = new Set<AllowedKey>(["a", "b", "c"]);

// const desiredResult = {
//   a: { foo: 1 },
//   b: {},
//   c: { foo: "Hi" }
// };

type Result = {
  [key in AllowedKey]: { foo?: string | number };
};

const y = collectionFromApi.reduce<Result>((acc, val) => {
  if (typeof val !== "object" || val === null) return acc;

  const key = Object.keys(val)[0];

  if (
    key === undefined ||
    !allowedKeys.has(key as AllowedKey)
  ) {
    return acc;
  }

  acc[key as AllowedKey] = (val as Result)[key as AllowedKey];
  return acc;

}, {} as Result);
console.log("Y", y);

Without lodash:

https://codesandbox.io/s/typescript-lodash-types-forked-11io7p?file=/src/index.type.ts

// import keyBy from "lodash/fp/keyBy";

type ObjectType = {
  [key: string]: {
    foo?: string | number;
  };
};

// const someOKCollection: Array<ObjectType> = [
//   { a: { foo: 1 } },
//   { b: {} },
//   { c: { foo: "Hi" } }
// ];

const collectionFromApi: unknown[] = [
  { a: { foo: 1 } },
  { b: {} },
  { c: { foo: "Hi" } },
  { d: { bar: "Hi" } }
];

type AllowedKey = "a" | "b" | "c";
const allowedKeys = new Set<AllowedKey>(["a", "b", "c"]);

// const desiredResult = {
//   a: { foo: 1 },
//   b: {},
//   c: { foo: "Hi" }
// };

type Result = {
  [key in AllowedKey]: { foo?: string | number };
};

const y = collectionFromApi.reduce<Result>((acc, val) => {
  if (typeof val !== "object" || val === null) return acc;

  const key = Object.keys(val)[0];

  if (
    key === undefined ||
    !allowedKeys.has(key as AllowedKey)
  ) {
    return acc;
  }

  acc[key as AllowedKey] = (val as Result)[key as AllowedKey];
  return acc;

}, {} as Result);
console.log("Y", y);

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