英文:
Excluding specific strings from type
问题
type TestName = 'test1' | 'test2' | 'test3';
type CustomName = `${string}` /// 需要排除 TestName
const name: CustomName = 'test'; // 允许
const name: CustomName = 'test1'; // 不允许
const name: CustomName = 'test2'; // 不允许
const name: CustomName = 'test3'; // 不允许
英文:
If I have a type as:
type TestName = 'test1' | 'test2' | 'test3';
How do I define a type of string with not the above?
type CustomName = `${string}` /// need to exclude TestName
const name: CustomName = 'test'; // allowed
const name: CustomName = 'test1'; // not allowed
const name: CustomName = 'test2'; // not allowed
const name: CustomName = 'test3'; // not allowed
答案1
得分: 0
就像 @Alex 说的,目前在 TypeScript 中似乎不可能实现。然而,你可以对函数参数做类似的操作:
type TestName = 'test1' | 'test2' | 'test3';
type NotTestName<T> = T extends TestName ? never : T;
function myFunc<T>(myValue: NotTestName<T>) {}
现在,调用这个函数的关键部分是确保将值缩小为 string
类型,因为实际上它不在 TestName
类型中,因此它会通过测试:
// 允许
myFunc('test' as const);
myFunc('abc' as const);
// 不允许
myFunc('test1' as const);
myFunc('test2' as const);
myFunc('test3' as const);
最终,如果你需要一个像在你的帖子中那样的最终常量值,你可以将它用作辅助函数:
type TestName = 'test1' | 'test2' | 'test3';
type NotTestName<T> = T extends TestName ? never : T;
function h<T>(value: NotTestName<T>): T { return value; }
// 允许
const name = h('test' as const);
// 不允许
const name = h('test1' as const);
const name = h('test2' as const);
const name = h('test3' as const);
请记住,如果字符串没有被缩小,测试将会错误地通过。
英文:
Like @Alex said, it doesn't seem to be possible with current TS. However, you can do something similar for a function parameter:
type TestName = 'test1' | 'test2' | 'test3';
type NotTestName<T> = T extends TestName ? never : T;
function myFunc<T>(myValue: NotTestName<T>) {}
Now, the key part on calling this function is to ensuring you get the value narrowed as string
is, indeed, not in the TestName
type and, therefore, it would pass the test:
// Allowed
myFunc('test' as const);
myFunc('abc' as const);
// Not allowed
myFunc('test1' as const);
myFunc('test2' as const);
myFunc('test3' as const);
Ultimately, if you need a final const value like in your post, you can use it as helper function:
type TestName = 'test1' | 'test2' | 'test3';
type NotTestName<T> = T extends TestName ? never : T;
function h<T>(value: NotTestName<T>): T { return value; }
// Allowed
const name = h('test' as const);
// Not allowed
const name = h('test1' as const);
const name = h('test2' as const);
const name = h('test3' as const);
You can run it in this playground.
Remember that if the string is not narrowed, you will get the test to wrongly pass.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论