admin管理员组

文章数量:1291050

Give then following:

interface Datum {
    [k: string]: any
}

type Data = Datum[]

const inner = (data: Data) => {
    console.log(data)
};


const outer = (data: Data | Data[]) => {
    inner(data) // expect type error?
};

I dont understand how I dont get a type error on the inner function call. I guess it has something to do with the generic. Cant figure out a way of rewriting.

Give then following:

interface Datum {
    [k: string]: any
}

type Data = Datum[]

const inner = (data: Data) => {
    console.log(data)
};


const outer = (data: Data | Data[]) => {
    inner(data) // expect type error?
};

I dont understand how I dont get a type error on the inner function call. I guess it has something to do with the generic. Cant figure out a way of rewriting.

Share Improve this question asked Mar 14, 2019 at 21:57 amwill04amwill04 1,3602 gold badges12 silver badges21 bronze badges 3
  • I think it's because you defined an array here type Data = Datum[] – Get Off My Lawn Commented Mar 14, 2019 at 21:59
  • @JohnMontgomery: I think the OP expects to get an error but isn't. – Felix Kling Commented Mar 14, 2019 at 22:00
  • @FelixKling Ah, I misread the question. – John Montgomery Commented Mar 14, 2019 at 22:01
Add a ment  | 

2 Answers 2

Reset to default 4

The Datum interface is just too broad. It will represent basically any object (ie indexable by a string and the result of the indexing operation is any).

Given the object type is soo wide, both Datum and Datum[] and Datum[][] are assignable to an array type, and thus you don't get any error. Make the interface a bit more specific and you get an error. Ex:

interface Datum {

    [k: string]: boolean | number | string;
}

type Data = Datum[]

const inner = (data: Data) => {
    console.log(data)
};


const outer = (data: Data | Data[]) => {
    inner(data) // error now
};

Or as @PatrickRoberts mentions in ments you can add a number index to the interface to make it explicitly inpatible with an array:

interface Datum {
    [i: number]: never
    [k: string]: any;
}

type Data = Datum[]

const inner = (data: Data) => {
    console.log(data)
};


const outer = (data: Data | Data[]) => {
    inner(data) // error
};

The best option would probably be using directly the object interface instead of Datum:

interface Datum {
    [k: string]: any
};
// This is an object interface.

type Data = object[]; // instead of Datum[]


const inner = (data: object[]) => {
    console.log(data)
};

Pd: I was looking for a solution for this same issue, used the solution from @titian-cernicova-dragomir which worked nicely. I ended up finding the object interface being used in the react-csv library.

本文标签: javascriptGeneric type array of objects in typescriptStack Overflow