Javascript Typescript:如何键入Ramda R.prop(键)T';不可分配给类型为';(s:{})=>;{}

Javascript Typescript:如何键入Ramda R.prop(键)T';不可分配给类型为';(s:{})=>;{},javascript,typescript,ramda.js,Javascript,Typescript,Ramda.js,打字错误 (方法)R.Static.prop(p:string):(obj:Record)=>T(+3个重载) 返回一个函数,当提供该函数时,对象将返回该对象的指定属性(如果存在) 类型为“(obj:Record)=>T”的参数不能分配给类型为“(s:{})=>{}”的参数。 参数“obj”和“s”的类型不兼容。 类型“{}”不可分配给类型“Record”。 类型{}.ts(2345)中缺少索引签名 代码: 如何使用此函数 在我的实际应用程序中,这就是我的IAsset对象的签名: expor

打字错误

(方法)R.Static.prop(p:string):(obj:Record)=>T(+3个重载)

返回一个函数,当提供该函数时,对象将返回该对象的指定属性(如果存在)

类型为“(obj:Record)=>T”的参数不能分配给类型为“(s:{})=>{}”的参数。 参数“obj”和“s”的类型不兼容。 类型“{}”不可分配给类型“Record”。 类型{}.ts(2345)中缺少索引签名

代码:

如何使用此函数 在我的实际应用程序中,这就是我的IAsset对象的签名:

export interface IAsset {
  [key: string]: string | number | undefined | boolean;
  availableSupply?: string;
  currency: string;
  exchange: string;
  exchange_base?: string;
  marketCap: number;
  name: string;
  percentage?: number;
  price: number;
  position?: number;
  value?: number;
  inWatchlist?: boolean;
}
但是,它仍然会产生以下类型脚本警告:

类型为“(obj:Record)=>T”的参数不能分配给类型为“(s:{})=>{}”的参数。 参数“obj”和“s”的类型不兼容。 类型“{}”不可分配给类型“Record”。 类型{}.ts(2345)中缺少索引签名


另请注意,Typescript正在扼杀漂亮的单行Ramda函数的乐趣。

对于您最初的问题:

我不是Ramda方面的专家,因此我可能在如何使用这些类型方面遗漏了一些东西,但看起来您可以通过使
updateKey
generic来消除类型错误:

const updateKey = <T, K extends string>(key: K) => R.lens(R.prop<K, T>(key), R.assoc(key));
我不确定,但我相信这是对
@types/ramda
项目的疏忽。您可以通过以下方式增强类型定义:

interface Static {
    prop<P extends keyof T, T>(p: P): (obj: Record<P, T>) => T;
    assoc<K extends keyof T, T>(prop: K): <T, U>(val: T, obj: U) => Record<K, T> & U;
}

type
'(s:{})=>{}
?@PrzemyslawPietrzak我相信,因为Typescript知道我正在更改对象的记录或键,R.prop在对象上工作,updateKey函数接收对象以及要更改的新值<代码>类型的参数'(obj:Record)=>T'不能分配给类型的参数'(s:{})=>{}.至于“Typescript正在扼杀漂亮的单行Ramda函数的乐趣”,我在过去两年中听到了很多这样的话。作为一名Ramda开发人员,我没有发现它是一个核心问题;我们正在编写一个JS库,希望尽可能让JS开发人员感到愉快。如果它能很好地与Typescript配合使用,我们会很高兴,但我们不会为此牺牲JSAPI。到目前为止,TS似乎并不真正支持我们使用的所有构造。我很想看到这种变化,但我并没有屏息以待。再想想,这毕竟可能不是一个疏忽。在中,ramda似乎接受数字键,但数组被转换为对象,它们的键被转换为字符串。这让我得出结论,这些方法实际上并不适用于数组或数字字符串,您可能应该使用我建议的第一个选项。谢谢!哦,是的,在我的IAsset中,关键总是字符串,我在我的示例中搞砸了。在我的界面中,实际上是
[key:string]:string | number | undefined | boolean
表示键是字符串,但该键可以属于
字符串
数字
未定义
或`布尔型。
// Changes value of key in object without mutation
export const updateKey = (key: IAsset[string]) => {
  if (key) {
    return R.lens(R.prop(key), R.assoc(key));  
  }
}
const updateKey = <T, K extends string>(key: K) => R.lens(R.prop<K, T>(key), R.assoc(key));
/**
 * Returns a function that when supplied an object returns the indicated property of that object, if it exists.
 */
prop<T>(__: Placeholder, obj: T): <P extends keyof T>(p: P) => T[P];
prop<P extends keyof T, T>(p: P, obj: T): T[P];
prop<P extends string>(p: P): <T>(obj: Record<P, T>) => T;
prop<P extends string, T>(p: P): (obj: Record<P, T>) => T;

/**
 * Makes a shallow clone of an object, setting or overriding the specified property with the given value.
 */
assoc<T, U>(__: Placeholder, val: T, obj: U): <K extends string>(prop: K) => Record<K, T> & U;
assoc<U, K extends string>(prop: K, __: Placeholder, obj: U): <T>(val: T) => Record<K, T> & U;
assoc<T, U, K extends string>(prop: K, val: T, obj: U): Record<K, T> & U;
assoc<T, K extends string>(prop: K, val: T): <U>(obj: U) => Record<K, T> & U;
assoc<K extends string>(prop: K): <T, U>(val: T, obj: U) => Record<K, T> & U;
interface Static {
    prop<P extends keyof T, T>(p: P): (obj: Record<P, T>) => T;
    assoc<K extends keyof T, T>(prop: K): <T, U>(val: T, obj: U) => Record<K, T> & U;
}
const updateKey = <K extends keyof IAsset>(key: K) => R.lens(R.prop<K, IAsset>(key), R.assoc<K, IAsset>(key));