用于转换键值对象中对象属性的Typescript generic
排序给我一个具有columnName和排序方向的对象,我想将其转换为键值对象进行mongoose排序 返回值不匹配我不知道我缺少什么 我有以下接口:用于转换键值对象中对象属性的Typescript generic,typescript,sorting,mongoose,Typescript,Sorting,Mongoose,排序给我一个具有columnName和排序方向的对象,我想将其转换为键值对象进行mongoose排序 返回值不匹配我不知道我缺少什么 我有以下接口: export enum SortDirection { asc = 'asc', desc = 'desc', } export class Sort<T> { columnName: keyof T direction: SortDirection } interface CriteriaRequestDto<
export enum SortDirection {
asc = 'asc',
desc = 'desc',
}
export class Sort<T> {
columnName: keyof T
direction: SortDirection
}
interface CriteriaRequestDto<T> {
sort: Sort<T>
}
type SortQuery<T> = {
[key in keyof T]?: SortDirection
}
buildSortQuery<T>(
criteria: CriteriaRequestDto<T>,
): SortQuery<T> {
if (!criteria || !criteria.sort) {
return {}
}
const { columnName, direction } = criteria.sort
return { [columnName]: direction }
}
导出枚举排序方向{
asc=‘asc’,
desc='desc',
}
导出类排序{
专栏名称:keyof T
方向:排序方向
}
接口标准requestedto{
排序:排序
}
类型SortQuery={
[key in keyof T]?:排序方向
}
buildSortQuery(
标准:CriteriaRequestDto,
):SortQuery{
如果(!criteria | |!criteria.sort){
返回{}
}
常量{columnName,direction}=criteria.sort
返回{[columnName]:方向}
}
问题在这里
返回{[columnName]:direction}
当您期望记录时,此符号表示{[prop:string]:SortDirection}
根据我的经验,TS不能很好地处理计算对象属性。99%将缩小为索引类型{[prop:string]:unknown}
为了解决这个问题,我做了一个record
函数,它将返回record
我是怎么做到的?我刚刚在函数中添加了一个重载
这是100%好的解决方案吗?
不,因为定义多个重载是一种好的做法
我想说重载比类型转换(as
operator)安全一点,但只安全一点
所以我只定义了record
函数的返回类型
函数记录(键:K,值:V):{[prop in K]:V}
功能记录(键:K,值:V){
返回{[key]:值}
}
因为下一个符号不起作用:
函数记录(键:K,值:V):{[prop in K]:V}{
返回{[key]:值}//错误
}
这里有完整的示例:
接口猫{
年龄:人数;
品种:弦;
}
枚举排序方向{
asc=‘asc’,
desc='desc',
}
接口排序{
专栏名称:keyof T
方向:排序方向
}
接口标准requestedto{
排序:排序
}
类型键=字符串|数字|符号;
函数记录(键:K,值:V):{[K中的prop]:V}
功能记录(键:K,值:V){
返回{[key]:值}
}
类型SortQuery=Partial
函数生成器查询(
标准:CriteriaRequestDto,
):SortQuery{
如果(!criteria | |!criteria.sort){
返回{}
}
常量{columnName,direction}=criteria.sort
返回记录(列名称、方向)
}
const sortQuery:sortQuery={}
sortQuery.age=SortDirection.asc//OK
常量排序:排序={
列名称:“年龄”//OK
方向:SortDirection.asc,//确定
}
常量标准:CriteriaRequestDto={
排序:排序//确定
}
const query=buildSortQuery(条件)
查询年龄
更新
请看一看。您不应该使用作为
操作符问题在于这里返回{[columnName]:direction}
当您期望记录时,此符号表示{[prop:string]:SortDirection}
根据我的经验,TS不能很好地处理计算对象属性。99%将缩小为索引类型{[prop:string]:unknown}
为了解决这个问题,我做了一个record
函数,它将返回record
我是怎么做到的?我刚刚在函数中添加了一个重载
这是100%好的解决方案吗?
不,因为定义多个重载是一种好的做法
我想说重载比类型转换(as
operator)安全一点,但只安全一点
所以我只定义了record
函数的返回类型
函数记录(键:K,值:V):{[prop in K]:V}
功能记录(键:K,值:V){
返回{[key]:值}
}
因为下一个符号不起作用:
函数记录(键:K,值:V):{[prop in K]:V}{
返回{[key]:值}//错误
}
这里有完整的示例:
接口猫{
年龄:人数;
品种:弦;
}
枚举排序方向{
asc=‘asc’,
desc='desc',
}
接口排序{
专栏名称:keyof T
方向:排序方向
}
接口标准requestedto{
排序:排序
}
类型键=字符串|数字|符号;
函数记录(键:K,值:V):{[K中的prop]:V}
功能记录(键:K,值:V){
返回{[key]:值}
}
类型SortQuery=Partial
函数生成器查询(
标准:CriteriaRequestDto,
):SortQuery{
如果(!criteria | |!criteria.sort){
返回{}
}
常量{columnName,direction}=criteria.sort
返回记录(列名称、方向)
}
const sortQuery:sortQuery={}
sortQuery.age=SortDirection.asc//OK
常量排序:排序={
列名称:“年龄”//OK
方向:SortDirection.asc,//确定
}
常量标准:CriteriaRequestDto={
排序:排序//确定
}
const query=buildSortQuery(条件)
查询年龄
更新
请看一看。返回{[columnName]:direction}
Typescript时,不应将用作
运算符。脚本将类型解释为{[x:string]:SortDirection;}
。此类型具有字符串
索引签名,因此不可分配给SortQuery
,它只允许T
的键作为属性。Typescript基本上是假设如果您从动态字符串
键创建对象,那么该对象必须允许任何字符串
键。这种假设是错误的
传播
另一方面,如果通过对象扩展将动态特性添加到现有对象,则Typescript将保留原始对象的类型,并且基本上忽略额外的特性
这是一种“黑客”解决方案,但如果将排序添加到空对象,则不会出现任何错误
return {
...{},
[columnName]: direction
}
Typescript将返回的对象解释为type{}
,这很好
const query: SortQuery<T> = {};
query[columnName] = direction;
return query;
const query: SortQuery<T> = {};
return {
...query,
[columnName]: direction
}
return {
[columnName]: direction
} as SortQuery<T>