打字稿。如何为以下类型创建通用辅助函数?
Typescript. How to create generic helper function for following type?
抱歉,标题不清楚,但我不知道如何快速描述我的问题。
我有一些具有一个文字值的类型和 object 具有这种类型的平面结构作为值(简化版):
type SomeType<T = string> = { value: T };
type SomeTypeMapped = Record<string, SomeType>;
我想写一个 helper(通用)来告诉 TS
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
具有以下类型:
const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
}
到目前为止我找到的最接近的解决方案是
function helper<V extends string, K extends string>(val: { [key in K]: SomeType<V> }) {
return val;
}
const a = helper({
A: { value: 'asd' }.
B: { value: 'qwe' }
});
// -->
const a: {
A: SomeType<"asd" | "qwe">;
B: SomeType<"asd" | "qwe">;
}
如果我尝试这样修改助手:
function helper<
V extends string,
K extends string,
T extends { [key in K]: SomeType<V> }
>(val: T) {
return val;
}
它将整个映射转换为常量文字类型:
const a: {
A: {
value: "asd";
};
B: {
value: "qwe";
};
}
这也接近我想要达到的目标,但我的第二点是可读性,因为
const a: {
A: SomeType<"asd">;
B: SomeType<"qwe">;
}
对于更复杂的示例(具有比单个 'value' 更多的字段)更具可读性。
我能以某种方式告诉 TS 字段 A
的类型完全是 SomeType<"asd">
以及字段 B
的类型是 SomeType<"qwe">
吗?
我会这样写 helper()
:
const helper =
<T extends Record<keyof T, string>>(val: { [K in keyof T]: SomeType<T[K]> }) => val;
您想传递给 SomeType
的 generic type parameter T
is a mapping from the keys of val
to the associated string
literal types。所以目的是当你打电话时
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
T
将被推断为 { A: "literal-1"; B: "literal-2" }
。那么 val
不是直接 T
类型,而是 mapped type {[K in keyof T]: SomeType<T[K]>}
.
请注意,编译器确实能够从 {[K in keyof T]: ...T[K]...}
形式的 同态映射类型 的值推断出类型 T
。在当前版本的 TS 手册中并不是真的 well-documented,但是手册的 now-deprecated v1 中有一段关于 inference from mapped types 的描述。
无论如何,这意味着当你在上面调用 helper()
时,T
被正确推断,并且 val
被推断为这种类型:
/* const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
} */
随心所欲。
抱歉,标题不清楚,但我不知道如何快速描述我的问题。
我有一些具有一个文字值的类型和 object 具有这种类型的平面结构作为值(简化版):
type SomeType<T = string> = { value: T };
type SomeTypeMapped = Record<string, SomeType>;
我想写一个 helper(通用)来告诉 TS
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
具有以下类型:
const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
}
到目前为止我找到的最接近的解决方案是
function helper<V extends string, K extends string>(val: { [key in K]: SomeType<V> }) {
return val;
}
const a = helper({
A: { value: 'asd' }.
B: { value: 'qwe' }
});
// -->
const a: {
A: SomeType<"asd" | "qwe">;
B: SomeType<"asd" | "qwe">;
}
如果我尝试这样修改助手:
function helper<
V extends string,
K extends string,
T extends { [key in K]: SomeType<V> }
>(val: T) {
return val;
}
它将整个映射转换为常量文字类型:
const a: {
A: {
value: "asd";
};
B: {
value: "qwe";
};
}
这也接近我想要达到的目标,但我的第二点是可读性,因为
const a: {
A: SomeType<"asd">;
B: SomeType<"qwe">;
}
对于更复杂的示例(具有比单个 'value' 更多的字段)更具可读性。
我能以某种方式告诉 TS 字段 A
的类型完全是 SomeType<"asd">
以及字段 B
的类型是 SomeType<"qwe">
吗?
我会这样写 helper()
:
const helper =
<T extends Record<keyof T, string>>(val: { [K in keyof T]: SomeType<T[K]> }) => val;
您想传递给 SomeType
的 generic type parameter T
is a mapping from the keys of val
to the associated string
literal types。所以目的是当你打电话时
const a = helper({
A: { value: 'literal-1' },
B: { value: 'literal-2' }
})
T
将被推断为 { A: "literal-1"; B: "literal-2" }
。那么 val
不是直接 T
类型,而是 mapped type {[K in keyof T]: SomeType<T[K]>}
.
请注意,编译器确实能够从 {[K in keyof T]: ...T[K]...}
形式的 同态映射类型 的值推断出类型 T
。在当前版本的 TS 手册中并不是真的 well-documented,但是手册的 now-deprecated v1 中有一段关于 inference from mapped types 的描述。
无论如何,这意味着当你在上面调用 helper()
时,T
被正确推断,并且 val
被推断为这种类型:
/* const a: {
A: SomeType<"literal-1">;
B: SomeType<"literal-2">;
} */
随心所欲。