我想获取具有已声明键/值的对象类型。 我有以下代码:
interface ConfigVar<T extends 'string' | 'number' | 'boolean'> {
env: string;
type: T;
}
interface ConfigMap {
[key: string]: ConfigVar<'string'> | ConfigVar<'number'> | ConfigVar<'boolean'>;
}
type ConfigType<T extends ConfigMap> = {
[P in Extract<keyof T, string>]:
T[P] extends ConfigVar<'string'> ? string :
T[P] extends ConfigVar<'boolean'> ? boolean :
T[P] extends ConfigVar<'number'> ? number :
never;
};
// usage
const configMap: ConfigMap = {
var1: {
env: 'VAR1',
type: 'string',
},
};
type ConfigMapType = ConfigType<typeof configMap>;
const config: ConfigMapType = {
var1: true, // Type 'boolean' is not assignable to type 'never'
// var1: 'str', // Type 'string' is not assignable to type 'never'
};
我的目标是使ConfigMapType
仅允许{ var1: string }
。打字稿可以吗?
答案 0 :(得分:1)
您的条件类型还可以,您唯一的问题就是保留configMap
的实际类型。如果您有一个显式类型注释,它将成为变量的最终类型,并且对象文字的类型将不起作用。同时保留约束和从对象文字推断类型的最佳方法是使用泛型函数:
interface ConfigVar<T extends 'string' | 'number' | 'boolean'> {
env: string;
type: T;
}
interface ConfigMap {
[key: string]: ConfigVar<'string'> | ConfigVar<'number'> | ConfigVar<'boolean'>;
}
type ConfigType<T extends ConfigMap> = {
[P in Extract<keyof T, string>]:
T[P] extends ConfigVar<'string'> ? string :
T[P] extends ConfigVar<'boolean'> ? boolean :
T[P] extends ConfigVar<'number'> ? number :
never;
};
// usage
const configMap = (<T extends ConfigMap>(o:T)=> o)({
var1: {
env: 'VAR1',
type: 'string',
},
});
type ConfigMapType = ConfigType<typeof configMap>;
const config: ConfigMapType = {
var1: 'str
};
答案 1 :(得分:1)
configMap
和var1
都是值,而不是类型。因此,TypeScript无法对其进行验证。您需要将var1
放在类型定义之一中,例如:
type ConfigMapType = ConfigType<{ var1: ConfigVar<'string'> }>;
或
interface ConfigVar<T extends 'string' | 'number' | 'boolean' = 'string'> {
env: string;
type: T;
}
type ConfigType<T> = {
[P in Extract<keyof T, string>]:
T[P] extends ConfigVar<'string'> ? string :
T[P] extends ConfigVar<'boolean'> ? boolean :
T[P] extends ConfigVar<'number'> ? number :
never;
};
const configMap = {
var1: <ConfigVar>{
env: 'VAR1',
type: 'string',
},
};
type ConfigMapType = ConfigType<typeof configMap>;
const config: ConfigMapType = {
var1: 'string',
};