Объявленный объект в константе только с точными свойствами, определенными в типе - PullRequest
1 голос
/ 10 апреля 2019

Мы используем машинописный текст вместе с JSDoc в нашем приложении на основе JS только для определения типов параметров, которые мы используем в наших функциях. В конкретном случае мы хотим иметь объекты с определенной структурой, и мы должны гарантировать, что каждый объект, объявленный под определенным типом, имеет только ожидаемые свойства

type Keys = 'foo' | 'bar';

type Things = {
  [K in Keys]: Thing;
}

interface Thing {
  a: string;
  b: string;
}

При создании объекта типа Things я ожидаю, что он будет иметь ТОЛЬКО атрибуты, определенные в Thing

const object = /** @type {Things} */ ({
  foo: { a: 'foo_a', b: 'foo_b' },
  bar: { a: 'bar_a', b: 'bar_b' }
})

Но практически мы можем объявить свойство abc без каких-либо жалоб со стороны Typescript. Он будет только жаловаться, если при попытке доступа к свойствам этого объекта мы вызываем свойство, которого нет в объявлении типа. Например, если мы сделаем object.abc, он будет жаловаться.

Error

Как вы и предполагали, это вызовет ошибку:

object.abc // abc is not defined in type Things

Нет ошибок

Добавление abc, которое не определено в Типе, не вызывает ошибку TS:

const object = /** @type {Things} */ ({
  foo: { a: 'foo_a', b: 'foo_b' },
  bar: { a: 'bar_a', b: 'bar_b' },
  abc: { a: 'abc_a', b: 'abc_b' },
})

Я бы хотел запретить объявление неопределенных в свойствах типа при создании объекта типа Things.

Детская площадка

Пример игровой площадки TypeScript

Кто-нибудь сталкивался с подобной проблемой?

Спасибо

1 Ответ

0 голосов
/ 10 апреля 2019

Как говорит @ExplosionPills, в:

const object = /** @type {Things} */ ({
    foo: { a: 'foo_a', b: 'foo_b' },
    bar: { a: 'bar_a', b: 'bar_b' },
    abc: { a: 'abc_a', b: 'abc_b' } // This shouldn't be allowed. Not defined in Keys 
})

«объект» не определен как тип «Вещи», следовательно, он не содержит ошибок, поскольку объект неявно имеет тип any, поэтому вы можете назначить ему все, что захотите.

Вам необходимо изменить код на:

const object : Things = /** @type {Things} */ ({
    foo: { a: 'foo_a', b: 'foo_b' },
    bar: { a: 'bar_a', b: 'bar_b' },
    abc: { a: 'abc_a', b: 'abc_b' } // This will now be highlighted as an error 
})

Выполнение этого только тогда позволяет объектам типа Вещи быть назначенными объекту. После внесения этого изменения вы увидите жалобу Typescript на ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...