如何将对象属性类型化为另一个属性的字符串';TypeScript中的字符串数组

如何将对象属性类型化为另一个属性的字符串';TypeScript中的字符串数组,typescript,Typescript,好 坏的 我一直在摆弄泛型之类的东西,但似乎无法让它发挥作用 假设您希望值的字符串元素是动态的,那么您就不能在TypeScript中将此类类型表示为具体的非泛型类型。相反,您将需要类似于以下内容的泛型类型: { values: ['John', 'Steven', 'Sarah'], oneOfValue: 'Joe', } 这是因为Acceptable中的泛型K将从values属性和oneOfValue属性中推断出来。你最终会得到“John”|“Steven”|“Sarah”和“Jo

坏的


我一直在摆弄泛型之类的东西,但似乎无法让它发挥作用

假设您希望
的字符串元素是动态的,那么您就不能在TypeScript中将此类类型表示为具体的非泛型类型。相反,您将需要类似于以下内容的泛型类型:

{
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe',
}
这是因为
Acceptable
中的泛型
K
将从
values
属性和
oneOfValue
属性中推断出来。你最终会得到
“John”|“Steven”|“Sarah”
“Joe”
的结合,这通常是人们希望编译器做的,但却没有抓住这一点


您真正想要的是告诉
inferAcceptable()
函数从
values
属性推断类型参数
K
,而不是从
oneOfValue
推断。这个想法被称为“非关键类型参数使用”,这是一个开放的特性请求(请参阅)。没有“官方”的方法可以做到这一点,但GitHub问题提供了一系列在各种情况下都能工作的技术和解决方法

是获取任何类型参数
T
,您不希望将其用于推理,并使用类似的
(T&{})
。让我们在这里试试:

const inferAcceptable = <K extends string>(a: Acceptable<K>) => a;

inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe',
}); // no error! K inferred as "John" | "Steven" | "Sarah" | "Joe"
这也是可行的,错误消息是您所期望的


好的,希望这些解决方案中的一个对你有效。祝你好运


假设您希望
值的字符串元素是动态的,那么您就不能在TypeScript中将此类类型表示为具体的非泛型类型。相反,您将需要类似于以下内容的泛型类型:

{
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe',
}
这是因为
Acceptable
中的泛型
K
将从
values
属性和
oneOfValue
属性中推断出来。你最终会得到
“John”|“Steven”|“Sarah”
“Joe”
的结合,这通常是人们希望编译器做的,但却没有抓住这一点


您真正想要的是告诉
inferAcceptable()
函数从
values
属性推断类型参数
K
,而不是从
oneOfValue
推断。这个想法被称为“非关键类型参数使用”,这是一个开放的特性请求(请参阅)。没有“官方”的方法可以做到这一点,但GitHub问题提供了一系列在各种情况下都能工作的技术和解决方法

是获取任何类型参数
T
,您不希望将其用于推理,并使用类似的
(T&{})
。让我们在这里试试:

const inferAcceptable = <K extends string>(a: Acceptable<K>) => a;

inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe',
}); // no error! K inferred as "John" | "Steven" | "Sarah" | "Joe"
这也是可行的,错误消息是您所期望的


好的,希望这些解决方案中的一个对你有效。祝你好运

const inferAcceptable = <K extends string>(v: { values: K[], oneOfValue: K & {} }) => v;
const good = inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Sarah',
}); // okay

const bad = inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe', // error!
  //~~~~~~~~ <-- "Joe" is not ("John" & {}) | ("Steven" & {}) | ("Sarah" & {})
});
type NoInfer<T> = [T][T extends any ? 0 : never];

const inferAcceptable = <K extends string>(v: { values: K[], oneOfValue: NoInfer<K> }) => v;

const good = inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Sarah',
}); // okay

const bad = inferAcceptable({
  values: ['John', 'Steven', 'Sarah'],
  oneOfValue: 'Joe', // error!
  //~~~~~~~~ <-- "Joe" is not "John" | "Steven" | "Sarah"
});