我想对以下代码进行编译时声明:
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在编译时是否可以这样做?我在asserts
(https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions)上看到了一些文档,但似乎并不打算用于这种情况
答案 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')