Javascript 如何更改索引表达式的类型?ie:c[k]
我的代码Javascript 如何更改索引表达式的类型?ie:c[k],javascript,typescript,indexof,keyof,Javascript,Typescript,Indexof,Keyof,我的代码 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)
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);
};
export interface ILPAsset {
symbol: string;
lastPayout: number;
historical: number;
}
IPAsset的界面
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);
};
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中如何处理这个问题
更新
顺便说一句,这是一个简单得多的方法,但是我得到了一个关于密钥检查的未来问题的很好的答案:D
export const filterAssets = (typed: string, assets: ILPAsset[]): ILPAsset[] => {
const checkSymbol = (asset: ILPAsset) =>
asset.symbol.includes(typed.toUpperCase());
return R.filter(checkSymbol, assets);
};
导致此问题的原因是您使用
k
作为c
的键。既然你提到你希望k
是ILPAsset的键,那就意味着c
应该是ILPAsset
。因此,签名应为:
const checkText = (k: keyof ILPAsset, c: ILPAsset) => (textMatch(txt, c[k].toLowerCase()) ? c : null);
遗留问题是,现在索引访问c[k]
将不是string
类型,因为ILPAsset
同时包含number
和string
键
我们有两种解决方案
我们可以检查c[k]
是否是string
,如果它没有返回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);
type StringKeys={[P in keyof T]:T[P]扩展字符串?P:never}[keyof T]
const checkText=(k:StringKeys,c:ILPAsset)=>(textMatch(txt,c[k].toLowerCase())?c:null);
注意:ILPAsset
唯一的字符串
键是symbol
,因此您可能应该评估是否需要k
参数。为什么不直接访问c.symbol
?如果c
是一个ILPAsset
为什么被声明为string
?@TitianCernicova Dragomir你是对的,我已经颠倒了键,但错误仍然是一样的:((k:string,c:keyof ILPAsset)
如何(k:keyof ILPAsset,c:ILPAsset)
是我所期望的,它应该基于您如何使用它。k
被用作c
的键。您说k
需要是ILPAsset
的键,所以如果k
是ILPAsset
的键,k
被用作c
的键,那么c
应该是ILPAsset
@TitianCernicova Dragomir啊,是的,它删除了k
下的错误,但是我在.toLowerCase()
上得到了一个错误,因为它仍然认为我正在尝试在数字上这样做。我想你不需要其他问题,我很快会回答,我们会从那里开始:)哇,太性感了!甚至不知道一种类型的从不
。。。我得慢慢读这类文字,看看到底是怎么回事,呵呵。你是对的,我应该使用c.symbol
@LeonGaban条件类型magic:)