【问题标题】:Typescript generic parameters assertion打字稿泛型参数断言
【发布时间】:2020-04-23 21:13:35
【问题描述】:

我想对以下代码进行编译时断言:

interface FormFields {
  [K: string]: string | boolean | number;
}

function FormTextInput<
  FieldName extends keyof Fields,
  Fields extends FormFields
>(fieldName: FieldName) { ... }

// should throw compile-time error:
FormTextInput<'someNumberField', { someNumberField: number }>('someNumberField')

// should NOT throw error:
FormTextInput<'someStringField', { someStringField: string }>('someStringField')

如果FieldName 引用非字符串值FieldsFormTextInput 总是会抛出错误

是否可以在编译时使用 Typescript 做到这一点?我在asserts (https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions) 上看到了一些文档,但它似乎并不适用于这种情况

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以定义帮助实用程序,它从源类型中选择具有字符串值的键:

    type PickKeysWithStringValue<T> =
      { [P in keyof T]: T[P] extends string ? P : never }[keyof T];
    
    type Test = PickKeysWithStringValue<{ foo: string, bar: number }> // results in "foo"
    

    function FormTextInput<Fields extends FormFields>(fieldName: PickKeysWithStringValue<Fields>) {  }
    
    // throws compile-time error:
    FormTextInput<{ someNumberField: number }>('someNumberField')
    
    // doesn't throw error:
    FormTextInput<{ someStringField: string }>('someStringField')
    

    Playground

    【讨论】:

    • 效果很好!但是问题:有没有办法改善错误信息?它只是说 Type '"someNumberField"' 不满足约束 '"someStringField"'
    • 我也确信这之前出现过,但是如果我将函数中泛型的顺序更改为 &lt;Fields, FieldName&gt; 为什么 TS 不能从参数中推断出第二个泛型的类型功能。不需要两次指定 fieldName 会很好
    • 为什么字段名需要泛型类型参数?
    • 我正在做一些魔术,所以用户只能在字段中传递与特定类型匹配的字段名称。为此,我需要它作为通用的
    • 你能在操场上添加一个例子吗?
    猜你喜欢
    • 2017-11-08
    • 2018-05-02
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2020-03-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多