Вложенный в Lint Typescript Generics - PullRequest
0 голосов
/ 18 марта 2020

Я ищу способ правильно express моей модели данных с определениями Tyepscript. Пока у меня есть следующее:

type Data = Record<string, string>;

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

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

Typescript Playground

A Context хранит набор DataContainers, где каждый DataContainer является обобщенным c через указанную c структуру данных D. Теперь я хочу express, чтобы каждая из этих структур данных D следовала универсальному типу Data. Т.е. состоящий из произвольных, но фиксированных <string, string> пар.

Я действительно не мог найти правильного решения для этого, лучшее, что я нашел, было DataContainer<D extends Data>. Считаете ли вы, что это хороший подход?

По крайней мере, следующее выдает мою ошибку задержки, как хотелось бы:

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

Поэтому я прихожу к выводу, что при написании <D extends Data> это также не будет разрешено для D иметь запись типа y: 2, правильно?

Теперь реальная проблема для меня заключается в том, что следующее не дает мне ошибку linting:

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

Я ищу способ смоделировать мои определения так, чтобы линтер мог пометить это как недействительное, потому что не существует D, чтобы вышеприведенный код был действительным контекстом. Это возможно? Спасибо за вашу помощь!

1 Ответ

1 голос
/ 18 марта 2020

Вы рядом. Проблема с DataContainer<any>. Любой эффективно отключает проверку типа, где он используется. Это означает, что, поскольку data в DataContainer<any> будет иметь тип any, никакие проверки не будут выполняться для свойства. Это независимо от того, какое ограничение вы накладываете D

Простое решение состоит в том, чтобы не использовать any, используйте ограничение в качестве аргумента типа для DataContainer:


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

Playground Link

...