如何以类型安全的方式声明选项,然后访问这些值?

huangapple go评论55阅读模式
英文:

How can I declare options in a type-safe way, then access the values?

问题

以下是代码部分的翻译:

// 1. 声明一个稀疏的选项集。
const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

// 2. 自己使用选项值。
console.log("Sum:", opts.a + opts.c.x);

// 3. 将选项传递给库。
initializeLibrary(opts);

以下是你的问题的翻译:

我正在使用一个提供了深度可选接口的库。

type Option = number | {
  x?: number;
  y?: number;
  z?: number;
}

interface Options {
  a?: Option;
  b?: Option;
  c?: Option;
  d?: Option;
}

function initializeLibrary(options: Options) {
  // ...
}

我想声明一组稀疏的选项,然后自己使用这些值,然后将这些选项传递给库。

这是可以工作的,但它*不是类型安全的*。我可以向`opts`添加不属于`Options`的键,但我不会得到错误。

```typescript
const opts = {
  a: 3,
  f: 3, // `f` 不属于 Options。
};

initializeLibrary(opts); // 没有错误!

如果我使用Options类型声明opts,那么它变得类型安全,但当我访问opts.a时会出现错误。

const opts: Options = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

console.log(opts.a + opts.c.x); // 错误:对象可能为 'undefined'。

我如何以类型安全的方式声明我的选项,同时仍然可以访问这些值?


我最好的尝试是重新声明我正在使用的Options接口的特定部分。

interface MyOptions extends Required<Pick<Options, "a" | "b" | "c">> {
  a: number;
  c: { x: number };
}
const opts: MyOptions = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

这可以工作;它将防止我添加不存在于Options中的属性。但我的实际用例要复杂得多,所以我想欺骗计算机来为我完成这项工作。

英文:

I'm working with a library that provides a deeply optional interface.

type Option = number | {
  x?: number;
  y?: number;
  z?: number;
}

interface Options {
  a?: Option;
  b?: Option;
  c?: Option;
  d?: Option;
}

function initializeLibrary(options: Options) {
  // ...
}

I want to declare a sparse set of options, use the values myself, then pass the options into the library.

// 1. Declare a sparse set of options.
const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

// 2. Use the option values myself.
console.log(&quot;Sum:&quot;, opts.a + opts.c.x);

// 3. Pass the options into the library.
initializeLibrary(opts);

This works, but it isn't type-safe. I can add keys to opts that don't belong to Options, and I won't get an error.

const opts = {
  a: 3,
  f: 3, // `f` doesn&#39;t belong to Options.
};

initializeLibrary(opts); // No error!

If I declare opts with type Options, then it becomes type-safe, but I get an error when I access opts.a.

const opts : Options = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

console.log(opts.a + opts.c.x); // Error: Object is possibly &#39;undefined&#39;

How can I declare my options in a type-safe way while still having access to the values?


My best effort is to re-declare the specific parts of the Options interface that I'm using.

interface MyOptions extends Required&lt;Pick&lt;Options, &quot;a&quot; | &quot;b&quot; | &quot;c&quot;&gt;&gt; {
  a: number;
  c: { x: number };
}
const opts: MyOptions = {
  a: 3,
  b: 4,
  c: { x: 3 },
};

This works; it will protect me from adding properties that don't exist in Options. But my actual use case is much more complex so I want to trick the computer into doing this work for me.

答案1

得分: 1

你可以在 v4.9 版本中使用 satisfies 关键字 如何以类型安全的方式声明选项,然后访问这些值?

const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
} 满足 Options;

console.log(opts.a + opts.c.x); // 一切正常
initializeLibrary(opts); // 一切正常
const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
  f: 3, // 会导致错误
} 满足 Options;
英文:

You can use the satisfies keyword as of v4.9 如何以类型安全的方式声明选项,然后访问这些值?

const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
} satisfies Options;

console.log(opts.a + opts.c.x); // all good
initializeLibrary(opts); // all good
const opts = {
  a: 3,
  b: 4,
  c: { x: 3 },
  f: 3, // will result in an error
} satisfies Options;

huangapple
  • 本文由 发表于 2023年2月10日 09:53:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75406233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定