Встречался с различными парсерами JSON. Когда то было сложно сразу преобразовать дату в тот объект который хочется, иногда Enum жил своей жизнью. И вот не давно повстречал один Фреймворк для NodeJS. Речь пойдет про Ts.ED.

Вообщем ничего необычного, создаём класс прописываем свойства, и указываем тип для свойств. Этот класс соответственно указываем как ожидаемый тип в теле запроса.

public class User {
	public middleName?: string;
}

Вроде понятно что ждём undefined или строку. Но я не обозначаю тип null для этого свойства. В запросе от клиента мне может прийти все что угодно в этом свойстве. Например null, в этом случае Ts.ED возьмёт значение null, да именно Js тип null, и обернёт значение в кавычки. На эндпоинте я уже получу не null а “null” и успешно запишу эту строку в БД. Фактически теперь у middleName будет строковое значение. Что я как-то совсем не ожидал. 

Ладно окей думаю что сделаю union type для этого свойства:

public middleName?: string | null;

И теперь все норм работает, но есть маленький нюанс, я использую этот класс также для БД. Не на прямую конечно а через TypeORM. В этом случае эта библиотека выдаст исключение о не соответствии типа в БД (Github issue). Для TypeORM не достаточно указать union тип, ещё нужна мета информация. Ее можно передать через декоратор @Column, который принимает опции в качестве параметра.

Хорошо, вообще я уже добавлял изначально следующие опции:

{ nullable: true }

Но этого не достаточно, погуглив какое то время я понял что если указывать такой union тип мне нужно явно обозначить тип для БД.

{ nullable: true, type: ‘character varying’ }

В итоге свойство будет выглядеть так:

@Column({ nullable: true, type: ‘character varying’ })
public middleName?: string | null;

Другой вариант решения возникшей ситуации это использовать Ts.ED декораторы. Для более старых версий, как у меня:

@Column({ nullable: true })
@Any(String)
public middleName?:string;

Тип String в принципе и есть union type string | null. С декоратором @Any или в последних версиях с декоратором @Nullable, Ts.ED больше не будет преобразовывать null в строку. 

Еще одно дополнение про Ts.ED, по умолчанию он все пытается преобразовать в строку, например, как значение в параметрах.

@QueryParams(INCLUDE) include: boolean;

Опять же include=true будет преобразовано в “true” если явно не обозначить в декораторе тип Boolean.

@QueryParams(INCLUDE, Boolean) include: boolean;

Комментарии (0)