打字稿通用参数声明

时间:2020-04-23 12:40:54

标签: typescript

我想对以下代码进行编译时声明:

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')

因此,如果FormTextInput引用了FieldName的非字符串值,则Fields总是抛出错误

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

1 个答案:

答案 0 :(得分: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

相关问题