TypeScript版本: 3.0.3
搜索字词:根据数组中的值进行输入
是否有当前或计划中的功能可以根据数组中的字符串创建类型?
码
const values = ['A', 'B']
type Foo = OneOf<values> // Is there a way of doing this?
const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values
类似于keyof
工作方式:
const values = {
A: 'A',
B: 'B'
}
type Foo = keyof typeof values
const v1: Foo = 'A'
const v2: Foo = 'D' // Type '"D"' is not assignable to type '"A" | "B"'
相关问题:https://github.com/Microsoft/TypeScript/issues/20965
链接到游乐场http://www.typescriptlang.org/play/#src = let%20vals1%20%3D%20%5B'A'%2C%20'B'%5D%0D%0Atype%20Foo1%20% 3D%20OneOf%3Cvals1%3E%20%2F%2F%20Is%20there%20a%20way%20of%20doing%20this%3F%0D%0A%0D%0Alet%20v1%3A%20Foo1%20%3D%20' A'%20%2F%2F%20This%20should%20work%0D%0Alet%20v2%3A%20Foo1%20%3D%20'D'%20%2F%2F%20This%20should%20give%20me%20an% 20错误%20since%20'D'%20没有%20exist%20in%20values%0D%0A%0D%0Alet%20vals2%20%3D%20%7B%0D%0A%20%20A%3A%20'A '%2C%0D%0A%20%20B%3A%20'B'%0D%0A%7D%0D%0Atype%20Foo2%20%3D%20keyof%20typeof%20vals2%0D%0Alet%20v3%3A%20Foo2 %20%3D%20'A'%0D%0Alet%20v4%3A%20Foo2%20%3D%20'D'%20%2F%2F%20Type%20'%22D%22'%20is%20not%20assignedable %20to%20type%20'%22A%22%20%7C%20%22B%22'
keyof
只起作用,因为它使用在编译时静态已知的信息。 TS中的类型是完全可擦除的,并且在转码后的代码中不存在,因此,根本不可能基于数组的运行时内容创建类型。
这个有可能:
function stringLiterals<T extends string>(...args: T[]): T[] { return args; }
type ElementType<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType> ? ElementType : never;
const values = stringLiterals('A', 'B');
type Foo = ElementType<typeof values>;
const v1: Foo = 'A' // This should work
const v2: Foo = 'D' // This should give me an error since 'D' doesn't exist in values
绝对不知道如何执行此操作。 #27179是相关的。
但是,那仍然使用编译器静态已知的信息。 那时我不明白只说”A” | “B”
的好处是什么。
@fatcerberus避免重复信息很有用-如果您只写const values = ["A", "B"]; type Foo = "A" | "B";
则很容易有人更改其中一个而忘记更改另一个。 您可以编写const values: Foo[] =["A", "B"];
,但是仍然很容易在Foo
添加一个附加条目,而忘记将其放在values
。
现在我们在哪里?
就像@ andy-ms所说的那样,避免手动重复信息非常有用。
就像@fatcerberus所说,类型是完全可擦除的。 有时,我们有时需要运行时检查例如从应用程序的非纯粹部分(例如Web服务或用户)获得的数据。
该问题被标记为“问题”,并且最近没有活动。 它已自动关闭以进行家政服务。 如果您仍在等待响应,那么问题通常更适合stackoverflow 。
在[email protected]及更高版本中。 这样解决
export const type = <const>[
'room',
'room_with_gifter',
'user_send'
];
export interface Activity {
id?: string;
type: typeof type[number];
}
代替这个:
export const items = <const>[
'room',
'room_with_gifter',
'user_send'
];
export interface Activity {
id?: string;
type: typeof items[number];
}
你可以这样做:
export const items = [
'room',
'room_with_gifter',
'user_send'
] as const;
export type Item = typeof items;
export interface Activity {
id?: string;
type: Item;
}
_真的不喜欢使用type
作为变量名。_
@ 7公里
在[email protected]及更高版本中。 这样解决
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
现在如果我在课堂上有这个怎么办?
class Class {
const list = <const>[
'room',
'room_with_gifter',
'user_send'
];
const withType: typeof list[number];
}
不起作用。 我也不能做this.list[number]
。 另外,对于我来说
用例,我无法将list
设置为static
@ 7公里
在[email protected]及更高版本中。 这样解决
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
现在如果我在课堂上有这个怎么办?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
不起作用。 我也不能做
this.list[number]
。 另外,对于我来说
用例,我无法将list
设置为static
@vegerot您不能在class
的范围内直接使用const
class
,因此语法不正确。
@ 7公里
在[email protected]及更高版本中。 这样解决
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
现在如果我在课堂上有这个怎么办?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
不起作用。 我也不能做
this.list[number]
。 另外,对于我来说
用例,我无法将list
设置为static
@vegerot您不能在
class
的范围内直接使用const
class
,因此语法不正确。
@ 7kms,我不好。 我复制并粘贴过多。 我的意思是
class Class {
private list = <const>[
'room',
'room_with_gifter',
'user_send'
];
private withType: typeof list[number];
// OR
private withType2: typeof this.list[number];
}
等等都不起作用。
另外,对于我的特定用例,我无法将列表设置为静态
@ 7公里
在[email protected]及更高版本中。 这样解决
export const type = <const>[ 'room', 'room_with_gifter', 'user_send' ]; export interface Activity { id?: string; type: typeof type[number]; }
现在如果我在课堂上有这个怎么办?
class Class { const list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; const withType: typeof list[number]; }
不起作用。 我也不能做
this.list[number]
。 另外,对于我来说
用例,我无法将list
设置为static
@vegerot您不能在
class
的范围内直接使用const
class
,因此语法不正确。@ 7kms,我不好。 我复制并粘贴过多。 我的意思是
class Class { private list = <const>[ 'room', 'room_with_gifter', 'user_send' ]; private withType: typeof list[number]; // OR private withType2: typeof this.list[number]; }
等等都不起作用。
另外,对于我的特定用例,我无法将列表设置为静态
class Class {
private list = [
"room",
"room_with_gifter",
"user_send"
] as const
private withType: Class["list"][number]
}
@vegerot这个怎么样?
@eyalch太棒了! 谢谢。 我认为解决方案将涉及typeof
或其他东西。 您能快速解释一下它是如何工作的,或者将我链接到讨论它的手册上吗?
@eyalch太棒了! 谢谢。 我认为解决方案将涉及
typeof
或其他东西。 您能快速解释一下它是如何工作的,或者将我链接到讨论它的手册上吗?
@vegerot当然,我相信它是“索引类型”。 它在手册中: https: //www.typescriptlang.org/docs/handbook/advanced-types.html#index -types
很高兴我能帮助你!
嘿%username%,如果ElementType
解决方案也不适合您,
注意array之后的as const
。 至关重要
最有用的评论
在[email protected]及更高版本中。 这样解决