typescript 将函数字符串作为类型参数文本字符串传递

w8f9ii69  于 2023-03-19  发布在  TypeScript
关注(0)|答案(1)|浏览(207)

我需要将一个字符串传递给一个类型,并将其用作文字字符串。
我必须改变什么,在UnprefixKeys-Utility中使用作用域字符串参数?
它应该使用函数作用域参数,而不添加额外的参数,如vars<T, Scope>(...
示例:

function vars<T>(scope: string, vars: UnprefixKeys<T, '--XXX-'>): T {
                                                      ^^^^^^^^  this should be replaced
                                                                with the scope var
  //...
  return <T>result
}

type SomeType = {
  '--YYY-a': number
  '--YYY-b': number
}

vars<SomeType>('--YYY-', {
  a: 1,
  b: 2,
})

// type utilities (they work)
type UnprefixKey<K extends PropertyKey, Prefix extends string>
  = K extends `${Prefix}${infer P}` ? P : K

type UnprefixKeys<T, Prefix extends string> = {
  [K in keyof T as UnprefixKey<K, Prefix>]: T[K]
}

返回类型应为:

{
  '--YYY-: number,
  '--YYY-: number,
}

但目前是(固定字符串--XXX-的原因)

{
  '--XXX-: number,
  '--XXX-: number,
}
xienkqul

xienkqul1#

...无需添加vars<T, Scope>(...等额外参数
UnprefixKeys需要使用字符串类型,但是如果不能向vars添加第二个泛型类型参数,则scope的类型将是string,而不是SomeLiteralType extends string
如果您真的不能添加类型参数,那就是答案。
我猜您已经确认要避免第二个类型参数,因为您需要显式指定T参数,这意味着您不能使第二个类型参数隐式化(根据用法推断),因此您必须键入常量两次(一次作为类型参数,一次作为运行时参数)。
要解决这个问题,可以编写一个函数,为特定作用域生成vars函数,如下所示:

function makeVars<Scope extends string>(scope: Scope) {
    return function vars<T>(vars: UnprefixKeys<T, Scope>): T {
        return <T>null;
    };
}

现在的用法是:

const varsYYY = makeVars("--YYY-");
varsYYY<SomeType>({
    a: 1,
    b: 2,
});

或者如果你喜欢:

makeVars("--YYY-")<SomeType>({
    a: 1,
    b: 2,
});

尝试在对象中使用无效键仍然会按预期失败:

varsYYY<SomeType>({
    a: 1,
    b: 2,
    q: 42, // <== Error here as desired
});

Playground链接

相关问题