zyfra / Prizm

Other
46 stars 16 forks source link

[Question] PrizmLet директива не вычисляет тип корректно в шаблоне(А17, typescript 5.4.5) #1880

Closed AntonGrekov closed 1 week ago

AntonGrekov commented 3 months ago

Библиотека

Компонент

PrizmLetDirective

Версия

NodeJS:

$ node -v
v16.14.2

Dependencies:

"@angular-devkit/build-angular": "17.3.4",
"@angular-devkit/core": "17.3.4",
"@angular-devkit/schematics": "17.3.4",
"@angular-eslint/eslint-plugin": "17.3.0",
"@angular-eslint/eslint-plugin-template": "17.3.0",
"@angular-eslint/template-parser": "17.3.0",
"@angular-extensions/svg-icons-builder": "^11.0.0",
"@angular/cli": "~17.3.0",
"@angular-builders/custom-webpack": "^17.0.2",
"@angular-material-components/datetime-picker": "^16.0.1",
"@angular-material-components/moment-adapter": "^16.0.1",
"@angular/animations": "17.3.4",
"@angular/cdk": "16.2.14",
"@angular/cdk-experimental": "16.2.14",

Prizm 4.3.5

"@prizm-ui/components": "~4.3.4",
"@prizm-ui/core": "~4.3.4",
"@prizm-ui/helpers": "~4.3.4",
"@prizm-ui/i18n": "~4.3.4",
"@prizm-ui/icons": "~4.3.4",
"@prizm-ui/theme": "~4.3.4",

Проект в котором используется Prizm

IDP

Вопрос

В нашем проекте используется А17 и Typescript версии 5.4.5. При использовании директивы prizmLet не в булевом контексте тип не вычисляется. Ниже пример кода:

Template:

<ng-container *evjLet="measures$ | async as measures">
  <cdk-accordion-item class="measures" #accordionItem="cdkAccordionItem">
    <event-measure-card
      *ngFor="let measure of measures | slice: 0:accordionItemsAmount"
      (openEditorModal)="openEditorModal(measure)"
      [measure]="measure"></event-measure-card>
    <div class="measures" *ngIf="accordionItem.expanded" @slideInOutTop>
      <event-measure-card
        *ngFor="let measure of measures | slice: accordionItemsAmount"
        (openEditorModal)="openEditorModal(measure)"
        [measure]="measure"></event-measure-card>
    </div>
  </cdk-accordion-item>

Model:

public measures$: BehaviorSubject<IEventMeasure[]> = new BehaviorSubject<IEventMeasure[]>([]);

Error:

Error: apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.html:19:42 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'IEventMeasure'.

19       (openEditorModal)="openEditorModal(measure)"
                                            ~~~~~~~

  apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.ts:23:16
    23   templateUrl: './event-measures.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component EventMeasuresComponent.

Error: apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.html:20:8 - error TS2740: Type '{}' is missing the following properties from type 'IEventMeasure': isEditable, canUpdateNameAndResponsible, id, name, and 4 more.

20       [measure]="measure"></event-measure-card>
          ~~~~~~~

  apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.ts:23:16
    23   templateUrl: './event-measures.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component EventMeasuresComponent.

Error: apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.html:24:44 - error TS2345: Argument of type 'unknown' is not assignable to parameter of type 'IEventMeasure'.

24         (openEditorModal)="openEditorModal(measure)"
                                              ~~~~~~~

  apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.ts:23:16
    23   templateUrl: './event-measures.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component EventMeasuresComponent.

Error: apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.html:25:10 - error TS2322: Type 'unknown' is not assignable to type 'IEventMeasure'.

25         [measure]="measure"></event-measure-card>
            ~~~~~~~

  apps/ejco/src/app/widgets/evj-events-workspace/shared/components/event-measures/event-measures.component.ts:23:16
    23   templateUrl: './event-measures.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component EventMeasuresComponent.

× Failed to compile.

В другом проекте при TypeScript версии 5.2.2 и А16 всё работает как ожидается

AntonGrekov commented 3 months ago

Добавляю еще инфу о сброщике и tsconfig.json, по всей видимости в этом причина:

project.json

{
  "name": "ejco",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/ejco/src",
  "prefix": "ejco",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@angular-devkit/build-angular:browser",
      "options": {
        "outputPath": "dist/apps/ejco",
        "index": "apps/ejco/src/index.html",
        "main": "apps/ejco/src/main.ts",
        "polyfills": "apps/ejco/src/polyfills.ts",
        "tsConfig": "apps/ejco/tsconfig.app.json",
        "assets": [
          "apps/ejco/src/favicon.ico",
          "apps/ejco/src/assets",
          {
            "input": "libs/admin/src/lib/assets",
            "glob": "**/*",
            "output": "assets/admin"
          },
          {
            "input": "libs/shared/src/lib/assets",
            "glob": "**/*",
            "output": "assets/shared"
          },
          {
            "input": "libs/pages/src/lib/assets",
            "glob": "**/*",
            "output": "assets/pages"
          }
        ],
        "styles": [
          "node_modules/@prizm-ui/theme/src/styles/styles.less",
          "node_modules/@prizm-ui/components/src/styles/styles.less",
          "apps/ejco/src/styles.scss",
          "node_modules/material-design-icons/iconfont/material-icons.css"
        ],
        "allowedCommonJsDependencies": ["lodash", "rxjs/internal/observable/dom/webSocket", "keycloak-js"]
      },
      "configurations": {
        "production": {
          "fileReplacements": [
            {
              "replace": "apps/ejco/src/environments/environment.ts",
              "with": "apps/ejco/src/environments/environment.prod.ts"
            }
          ],
          "optimization": {
            "styles":
            {
              "inlineCritical":
              false
            }
          },
          "outputHashing": "all",
          "sourceMap": false,
          "namedChunks": false,
          "extractLicenses": true,
          "vendorChunk": false,
          "buildOptimizer": true
        },
        "development": {
          "buildOptimizer": false,
          "optimization": false,
          "vendorChunk": true,
          "extractLicenses": false,
          "sourceMap": true,
          "namedChunks": true
        }
      }
    },
    "serve": {
      "executor": "@angular-devkit/build-angular:dev-server",
      "options": {
        "buildTarget": "ejco:build"
      },
      "configurations": {
        "production": {
          "buildTarget": "ejco:build:production"
        },
        "development": {
          "buildTarget": "ejco:build:development"
        }
      },
      "defaultConfiguration": "development"
    },
    "extract-i18n": {
      "executor": "@angular-devkit/build-angular:extract-i18n",
      "options": {
        "buildTarget": "ejco:build"
      }
    },
    "lint": {
      "executor": "@nx/eslint:lint",
      "outputs": ["{options.outputFile}"]
    },
    "test": {
      "executor": "@angular-devkit/build-angular:karma",
      "options": {
        "main": "apps/ejco/src/test.ts",
        "tsConfig": "apps/ejco/tsconfig.spec.json",
        "karmaConfig": "apps/ejco/karma.conf.js",
        "polyfills": "apps/ejco/src/polyfills.ts",
        "styles": [],
        "scripts": [],
        "assets": []
      }
    }
  }
}

tsconfig.json

{
  "extends": "../../tsconfig.base.json",
  "files": [],
  "include": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.spec.json"
    },
    {
      "path": "./tsconfig.editor.json"
    }
  ],
  "compilerOptions": {
    "target": "es2022",
    "useDefineForClassFields": false,
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictTemplates": true
  }
}

tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "types": [],
    "target": "ES2022",
    "useDefineForClassFields": false
  },
  "files": ["src/main.ts", "src/polyfills.ts"]
}
ozknemoy commented 3 months ago

вот простенький сетап как воспроизвести. на чистом проекте настройки позволяют собрать билд, но тип теряется

<ng-container *prizmLet="5 as prizmLet">{{ prizmLet }}</ng-container>
<ng-container *ngIf="5 as ngIf"> {{ ngIf }} </ng-container>

тут переменная объявленная в *ngIf имеет тип image

а в prizmLet потеряла image

и до кучи наша собственная директива evjLet image

imonogarov commented 3 weeks ago

Удалить наш Let, т.к. в Angular 18 есть нативная альтернатива