简体   繁体   English

将泛型类型约束为文字类型

[英]Constrain a generic type to be a literal type

My question is two-fold: 我的问题是双重的:

  1. I would like to know if there is a way in TypeScript to constrain a generic to be a literal type of some kind. 我想知道TypeScript中是否有一种方法可以将泛型约束为某种类型的文字类型。 What I mean by this is something like function foo<T is a string literal>(...) . 我的意思是function foo<T is a string literal>(...) The closest I have come to this behaviour is function foo<T extends string> , but this allows unions of string literals and the type "string" itself as values for T. 我最接近这种行为的是function foo<T extends string> ,但这允许字符串文字的联合和类型“字符串”本身作为T的值。
  2. If this is not possible in TypeScript 2.1, would it make sense from a design perspective to implement such a feature? 如果在TypeScript 2.1中无法实现这一点,那么从设计角度来看,实现这样的功能是否有意义?

My use-case is to define a curried function prop like this: 我的用例是定义一个像这样的curried函数prop

function prop<K extends string, U>(name: K): <T extends { [P in K]: U  }>(obj: T) => T[K] {
    return (obj) => obj[name];
}

prop<'name', number>("name")({
    name: 3
})

This example works as expected if K is a string literal, but the typechecking of the function kind of breaks down K is string . 如果K是字符串文字,则此示例按预期工作,但是功能类型的类型检查Kstring

I know it's a bit contrived; 我知道这有点做作; please not my goal is not to solve a practical problem (although it would) but more to experiment with TypeScript's type system. 请不是我的目标不是解决一个实际问题(尽管它会),而是更多地尝试使用TypeScript的类型系统。

Thank you! 谢谢!

I think the problem here is that you're putting the cart before the horse in terms of your generic constraints: there is no sense in trying to constrain the allowed keys before you know the object. 我认为这里的问题在于你根据通用约束把马放在马前:在你知道对象之前尝试约束允许的键是没有意义的。

Here's an example that does what I think you're trying to accomplish: 这是一个我想你想要完成的例子:

function propGetter<O>(o: O): <K extends keyof O>(key: K) => O[K] {
    return k => o[k];
}

let prop = propGetter({
    id: 10,
    firstName: "Dununuh Hunudunuh"
});

let id = prop("id");               // number
let firstName = prop("firstName"); // string
let foo = prop("foo");             // Type error

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM