代码之家  ›  专栏  ›  技术社区  ›  Leon Gaban

如何更改索引表达式的类型?I:C[K]

  •  0
  • Leon Gaban  · 技术社区  · 6 年前

    我的密码

    import * as R from 'ramda';
    
    import { ILPAsset } from 'shared/types/models';
    
    interface TextMatchFunction {
      (part: string, typed: string): boolean;
    }
    
    const textMatch: TextMatchFunction = (part: string, typed: string) => typed.search(part) !== -1;
    
    export const filterAssets = (txt: string, assets: ILPAsset[]): ILPAsset[] => {
      const checkText = (k: string, c: keyof ILPAsset) => (textMatch(txt, c[k].toLowerCase()) ? c : null);
      const curriedCheckText = R.curry(checkText);
      // @ts-ignore
      const bySymbol = R.map(curriedCheckText('symbol'), assets);
      return R.reject(R.isNil, bySymbol);
    };
    

    iPasset接口

    export interface ILPAsset {
      symbol: string;
      lastPayout: number;
      historical: number;
    }
    

    这一行有问题:

    const checkText = (k: string, c: keyof ILPAsset) => (textMatch(txt, c[k].toLowerCase()) ? c : null);
    

    typescript要求k为数字 c[k] ,当它实际上是ilpasset中对象的键时,它是字符串,在我的情况下 symbol .

    这将如何在typescript中处理?

    更新

    一个更简单的方法来做这个btw,但是我得到了一个关于密钥检查未来问题的很好的答案:d

    export const filterAssets = (typed: string, assets: ILPAsset[]): ILPAsset[] => {
      const checkSymbol = (asset: ILPAsset) => 
        asset.symbol.includes(typed.toUpperCase());
      return R.filter(checkSymbol, assets);
    };
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    6 年前

    问题是因为您正在使用 k 作为关键 c . 自从你提到你期望的 K 成为一个 keyof ILPAsset 那就意味着 C 应该是 ILPAsset . 所以签名应该是:

    const checkText = (k: keyof ILPAsset, c: ILPAsset) => (textMatch(txt, c[k].toLowerCase()) ? c : null);
    

    剩下的问题是现在索引访问 c[k] 将不是类型 string 自从 伊尔帕塞特 包含两个 number 一串 钥匙。

    我们有两种解决办法。

    我们可以检查一下 C[K] 是一个 一串 如果它不回来 null :

    const checkText = (k: keyof ILPAsset, c: ILPAsset)  => {
      const v = c[k];
    
      return typeof v === 'string' ? (textMatch(txt, v.toLowerCase()) ? c : null): null;
    } 
    

    我们也可以过滤钥匙 K 只能是一把钥匙 一串

    type StringKeys<T> = { [P in keyof T] : T[P] extends string ? P: never}[keyof T]
    const checkText = (k: StringKeys<ILPAsset>, c: ILPAsset)  => (textMatch(txt, c[k].toLowerCase()) ? c : null);
    

    注释 唯一的 一串 关键 伊尔帕塞特 symbol 所以也许你应该评估一下 K 参数。为什么不直接进入 c.symbol ?