英文:
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("Sum:", 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'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 'undefined'
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<Pick<Options, "a" | "b" | "c">> {
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;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论