Как писать код, который пишет код на TS

Валерий Кузьмин, СКБ Контур

Perm Tech Talks, 2017

Kontur.Recognition

Проблема - надо писать 2 раза

  • Data Transfer Object
  • Валидации

Подходы

JS

JS

C#

C#

JS

node.js

edge.js

codegen

Open-source решения

  • JSIL - все что угодно, страшный JS
  • NetJS - с ограничениями, TS
    • namespaces
    • overloads
    • async
    • RegEx named groups
private static ValidateInn(inn: string): List<ValidationResult>
{
    var list: List<ValidationResult> = new List<ValidationResult>();
    var flag: boolean = InnKppHelper.IsInnForIndividual(inn);
    var flag2: boolean = InnKppHelper.IsInnForLegalEntity(inn);
    if (flag || flag2)
    {
        if (!InnKppHelper.IsInnChecksumValid(inn))
        {
            var arg_5D_0: List<ValidationResult> = list;
            var validationResult: ValidationResult = new ValidationResult();
            validationResult.Message = "Неверная контрольная сумма ИНН";
            arg_5D_0.Add(validationResult);
        }
    }
    ....
}

На выходе

Как это работает

Krec.Isomorphic.dll

ILSpy

NRefactory

AST (C#)

Как это работает

AST (C#)

AST (TS)

CsToTs

Krec.Isomorphic.ts

TsOutputVisitor

Как это работает

Krec.Isomorphic.ts

guid.ts

mscorlib.ts

Готовая сборка

Архитектура

C#

DLL

TypeScript

JS

PROFIT!

NetJS

webpack

msbuild

???

Архитектура

C#

DLL

TypeScript

Fixed TS

JS

PROFIT!

NetJS

webpack

gulp

msbuild

???

2

1

(1) webpack: референсы

///<reference path='mscorlib.ts'/>

... my ts code ...
import {
    NObject,
    Exception,
    NBoolean,
    ...
} from './mscorlib.ts';

(1) webpack: экспорты

class DocumentExtensions extends NObject ...
export class DocumentExtensions 
    extends NObject ...
+ enum, interface

(2) netjs: mscorlib.ts

class NString {
...
    static TrimEnd(str: string, trimChars: number[]): string
    {
	throw new NotImplementedException();
    }
...
}

(2) netjs: ES3

class Person {
    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}
class Person extends NObject {
    name: string;
    SetName(value: string): void
    {
        this.name = value;
    }
    GetName(): string
    {
        return this.name;
    }
}

tsc.exe -t ES3 mscorlib.es3.ts Library.ts --out Library.js

В итоге:

  • Кода стало меньше
  • Писать на JS сильно проще
  • Писать на C# чуть сложнее
  • Общая логика синхронизирована

Бонус: схема

{
    documents: [{...},{...}]
}
{
    documents: List<Document>
}

Runtime

Спасибо за внимание!

Вопросы?

  • https://slides.com/malcoriel/netjs-at-perm
  • https://github.com/kontur-recognition/Netjs

malcoriel@gmail.com

malcoriel

netjs-at-perm

By Valeriy Kuzmin

netjs-at-perm

  • 710