typescript - 带有 keyof 的打字稿预设键
问题描述
我想有一个预设的键,但我不想限制用户只使用这些。
type B = {
a: string;
b: number;
}
type T = keyof B | string;
function someFunc(key: T) {}
someFunc(); // key type is `T`
在上述情况下,我想为a
and自动完成b
,但用户也可以使用他们想要的任何字符串。是否可以?
解决方案
编译器将联合简化"a" | "b" | string
为string
. 从类型系统的角度来看,这是“正确的”,因为您想接受任何string
值,并且"a"
只是"b"
特定的值。但是从 IntelliSense 和 IDE 提示的完成列表的角度来看,类型string
已经丢失了信息"a" | "b" | string
。string
理想情况下,您希望编译器在记住建议 "a"
以及"b"
尝试在 IDE 中写入该类型的值时继续折叠此类联合。
Unfortunately this is currently not a feature of TypeScript. There are actually multiple issues in GitHub filed about this, and you may want to go to one or all of them and give them a . The big one is probably microsoft/TypeScript#29729, and it looks like this issue will actually be reviewed by the design team soon (as of 2020-05-23). There's also microsoft/TypeScript#26277, microsoft/TypeScript#33471, and microsoft/TypeScript#34714. For the short term, though, this is not part of the language, and so if you want something like it you'll have to use a workaround.
The workarounds I've seen involve defining a type for which the compiler will accept any string
value, but a reduction to string
is avoided or deferred because it depends on some unspecified generic type. For example:
function someFunc<S extends string>(key: S | keyof B) { }
Here, we've made someFunc()
generic in S
which is constrained to string
. The key
parameter is of type S | keyof B
. Whatever string value you type in for key
will end up being the inferred type for S
, so it will accept any string
:
someFunc("a"); // okay
someFunc("b"); // okay
someFunc("omega"); // okay
But the autocomplete will suggest "a"
and "b"
because it doesn't know what S
is when it has to make the suggestions:
Hooray! I'm sure there are plenty of edge cases involved in turning what was supposed to be a concrete type into a generic type, and you might conclude that the side-effects are not worth it for you. It is a workaround after all, so tread lightly.
Anyway, hope that helps; good luck!
推荐阅读
- excel - 任务计划程序打开 Excel 文件但继续运行且未完成
- ios - 有没有办法在 Google Maps API 的应用程序加载时打开 InfoWindow?
- c# - ASP.NET CORE REST API(401 未经授权)
- java - HTTP 响应 411:与通信时需要的长度
- javascript - 为什么我的计算器连接而不是执行操作?
- javascript - document.querySelectorAll 在使用 chrome 80 运行的赛普拉斯中不起作用
- c# - 如何在 T-SQL 中将日期时间字段与字符串连接起来
- javascript - 打字稿:如何从两组不同的对象中获取具有相同属性值但不同键的对象
- angular - 合并两个 obervable,但在第一个完成之前不触发第二个
- python - 双重直接整合