简体   繁体   中英

Lint nested Typescript Generics

I am looking for a way to correctly express my data model with tyepscript definitions. So far I have the following:

type Data = Record<string, string>;

interface DataContainer<D extends Data> { 
    id: string;    
    data: D;
}

interface Context {
    dataContainers: DataContainer<any>[];
}

Typescript Playground

A Context stores a set of DataContainers , where each DataContainer is generic over a specific data structure D . Now what I want to express is that each of those data structures D should follow a universal type Data . Ie consisting of arbitrary but fixed <string, string> pairs.

I really could not find a proper solution for that, the best thing I found was DataContainer<D extends Data> . Do you think that's a good approach?

At least the following gives my a linting error as desired:

interface MyData extends Data {
    x: "1",
    y: 2, // Lint error, because not string. (As I want it)
}

So I conclude that when writing <D extends Data> it would also not be allowed for D to have an entry like y: 2 , correct?

Now a real problem for me is that the following does not give me a linting error:

const myContext: Context = {
    dataContainers: [
        {
            id: "123",
            data: {
                x: 1, // This should be marked by the linter
                y: "2", 
                z: {a: 1}, // This also
            }
        }
    ]
}

I am looking for a way to model my definitions such that a linter would mark this as invalid, because there exists no D such that the above would be a valid Context. Is that possible? Thanks for your help!

You are close. The issue is with DataContainer<any> . Any effectively turns off type checking where it is used. This means that since data in DataContainer<any> will be of type any , no checks will be done for the property. This is regardless of the constraint you put on D

The simple solution is to not use any , use the constraint as the type argument to DataContainer :


interface Context {
    dataContainers: DataContainer<Data>[];
}

Playground Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM