首页 > 解决方案 > 带有 keyof 的打字稿预设键

问题描述

我想有一个预设的键,但我不想限制用户只使用这些。

type B = {
  a: string;
  b: number;
}

type T = keyof B | string;


function someFunc(key: T) {}

someFunc(); // key type is `T`

在上述情况下,我想为aand自动完成b,但用户也可以使用他们想要的任何字符串。是否可以?

标签: typescript

解决方案


编译器将联合简化"a" | "b" | stringstring. 从类型系统的角度来看,这是“正确的”,因为您想接受任何string值,并且"a"只是"b"特定的值。但是从 IntelliSense 和 IDE 提示的完成列表的角度来看,类型string已经丢失了信息"a" | "b" | stringstring理想情况下,您希望编译器在记住建议 "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:

enter image description here

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!

Playground link to code


推荐阅读