【问题标题】:How to fix types parameters in typescript function?如何修复打字稿函数中的类型参数?
【发布时间】:2022-01-26 17:01:29
【问题描述】:

有一个功能:

function getFirstObjectArray<T>(obj: T): any | null {
    const keys = Object.keys(obj);
    
    if(keys.length) {
        const [key, ...restk] = keys;
        const [firstObject, ...restv] = obj[key] || [];
        return firstObject;
    }

    return null;
}

我有收入对象:

let obj = {100: [1, 2, 3], 200: [4, 5, 6]}  

结果我尝试获取1。第一个元素的值是第一个对象。

我收到此错误:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.
  No index signature with a parameter of type 'string' was found on type 'unknown'.

所以,我尝试获取第一个对象,然后从数组中获取第一个元素。

【问题讨论】:

  • 为什么是const [firstObject, ...restv] = obj[key] || []; 而不是const firstObject = obj[key]
  • 1.如果您希望T 是一个对象类型,您需要声明这个&lt;T extends {}&gt;。 2. 这行const [firstObject, ...restv] = obj[key] || []; 没有任何意义:您希望每个对象访问都是一个数组?如果是这种情况,您也需要为此限制泛型。
  • 因为我有这个初始对象:let obj = {100: [1, 2, 3]}
  • 再一次,如果你希望 T 是一个特定形状的对象,那么你需要告诉类型检查器,比如@ 987654331@ 然后&lt;T extends MyType&gt;。或者根本不使用泛型,不清楚为什么?为什么需要一个通用函数来处理一个特定的对象?
  • 是的,让我们不要使用泛型,反正我得到一个错误。如何正确制作?

标签: typescript


【解决方案1】:

认为这就是你所追求的:

interface MyInterface {
    [key: string]: number[] | any
}

function getFirstArrayMember(obj: MyInterface): number
function getFirstArrayMember(obj: any): null 
function getFirstArrayMember(obj: MyInterface | any): null | number {
    let result: number | null = null;
    Object.values(obj).map(val => {
        if (result === null && Array.isArray(val)) result = val[0]
    })
    return result
}

let obj = {100: [1, 2, 3], 200: [4, 5, 6]} 
let one = getFirstArrayMember(obj) // number

这将返回对象中第一个数组的第一个元素,保持类型安全。如果对象没有数组键,则返回 null。使用overload,因此您不必检查联合返回类型以获取编译时值。

Playground

【讨论】:

  • 为什么我不能使用泛型类型?我不知道作为参数函数传递的结果类型
  • 你可以,我只是觉得你不需要。您可能无法让编译器正确推断类型。
【解决方案2】:

如果您不在其他参数或函数的返回值中使用T,那么您根本不需要泛型。此外,如果您的输入对象的每个值都有一个数字数组,只需按原样输入:

function getFirstObjectArray(obj: { [key: PropertyKey]: number[] }): any | null {
    const keys = Object.keys(obj);

    if (keys.length) {
        const [key, ...restk] = keys;
        const [firstObject, ...restv] = obj[key] || [];
        return firstObject;
    }

    return null;
}

TypeScript playground

【讨论】:

    【解决方案3】:

    试试

    <T extends Record<string, number[]>>
    

    【讨论】:

    • 不是 DV,但这将受益于更多解释。
    • 我不知道真正的类型,所以不适合我
    • 这只是一个例子,你可以试试function getFirstObjectArray&lt;T&gt;(obj: Record&lt;string,T[]&gt;): T | null
    猜你喜欢
    • 2020-12-28
    • 2019-03-20
    • 2022-01-12
    • 1970-01-01
    • 2019-07-05
    • 2020-05-11
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    相关资源
    最近更新 更多