错误 TS2322:类型 'keyof T' 不可分配给类型 'T'。在打字稿 4.4 中

error TS2322: Type 'keyof T' is not assignable to type 'T'. in typescript 4.4

我有一个函数 selectProperties 到 select 来自某个接口的键值,并在升级到 typescript 4.4 后得到错误 error TS2322: Type 'keyof T' is not assignable to type 'T'.typescript playground,谁知道我怎么走动?

export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
): T => {
  const defaultVal: T = {} as T;
  return (Object.keys(properties) as (keyof T)[])
    .filter((key) => keys.includes(key))
    .reduce(
      (acc, key) => ({
        ...acc,
        [key]: properties[key],
      }),
      defaultVal
    );
};

看起来您希望减少到 return 类型 T 的对象,当它只接受与它正在迭代的数组值类型匹配的默认值时,最终 returns 一些值的组合。 Reduce 最终只会从 T.

的键中 returning 一个值

如果您选择了一些类型为 T 的键,则不能将 T 作为您的 return 类型。您实际上是在根据给定键的列表创建分部类型。

您可以 return 通过使用 forEach 并改变 return 对象。


export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
) => {
  const defaultVal: Partial<T> = {};
  
  Object.keys(properties)
    .filter(key => keys.includes(key))
    .forEach(key => {defaultVal[key as keyof T] = properties[key]});

  return defaultVal
};


如果你真的想从 T 上的选定键中获取值,那么你可以改用 map...


export interface QueryActioned {
  event: string;
  properties:string
}
export interface QueryStarted {
  event: number
  properties: number
}
export type QueryProps = Partial<(QueryActioned & QueryStarted)['properties']>;

const selectProperties = <T extends Partial<QueryProps>>(
  keys: (keyof T)[],
  properties: T
): (T[keyof T])[] => {
  return Object.keys(properties)
    .filter(key => keys.includes(key))
    .map(key => properties[key]);
};


无论哪种方式,reduce 都会组合 keyof T 数组中的所有值,并且您将 return 类型指定为 T,这将是错误的来源。