Как заставить eslint/TypeScript выводить значение сигнала Angular для предложения if?

Я пытаюсь использовать значение сигнала, которое может быть undefined, но не понимаю, как сообщить линтеру, что значение определено, после того, как я проверю, что оно действительно определено.

Пример

export class MyComponent {
  mySignal$: WritableSignal<{ msg: string } | undefined> = signal(undefined);

  constructor() {
    this.mySignal$.set({ msg: 'Hello there!' });

    effect(() => {
      if (this.mySignal$()) {
        console.info(this.mySignal$().msg) // Object is possibly 'undefined'.ts(2532)
        
        // Works but feels like there should be an easier way
        // console.info((this.mySignal$() as { msg: string }).msg)
      }
    });
  }
}

Соответствующие установленные пакеты

"@angular-eslint/eslint-plugin": "16.0.3"
"@angular-eslint/eslint-plugin-template": "16.0.3"
"@angular-eslint/template-parser": "16.0.3"
"@nx/eslint-plugin": "16.8.1"
"@typescript-eslint/eslint-plugin": "5.60.1"
"@typescript-eslint/parser": "5.60.1"
"eslint": "8.46.0"

Редактировать 1

Я слишком сильно упростил свой реальный код для примера, не показывая всей проблемы. Но я все равно буду использовать Not Null Assertion из ответа Наренса.

export class MyComponent {
  msgSignal$: WritableSignal<{ msg: string } | undefined> = signal(undefined);
  resultSignal$: WritableSignal<string | undefined> = signal(undefined);

  constructor() {
    this.msgSignal$.set({ msg: 'Hello there!' });
    this.resultSignal$.set('General Kenobi');

    effect(() => {
      if (this.msgSignal$() && this.resultSignal$()) {
        this.msgSignal$().msg = this.resultSignal$() // Object is possibly 'undefined'.ts(2532)
    
        // Fix
        // this.msgSignal$()!.msg = this.resultSignal$()!
      }
    });
  }
}
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем использовать либо TypeScript Not Null Assertion (!.), либо Оператор безопасной навигации Typescript (?.), чтобы обойти эту ошибку!

Будет отображена ошибка TypeScript, поскольку вы определили тип как { msg: string } | undefined. Таким образом, существует вероятность того, что переменная будет undefined, когда мы получим доступ к свойству с неопределенным значением, произойдет исключение.

TypeScript предупреждает об этом, поэтому мы можем утверждать, что оно не будет нулевым, используя !., но я думаю, что для этого конкретного сценария ?. является лучшим решением, поскольку он будет обрабатывать неопределенные сценарии.

TypeScript Playground -> проверьте, как TypeScript конвертируется в JS

import { Component, WritableSignal, effect, signal } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <a target = "_blank" href = "https://angular.dev/overview">
      Learn more about Angular
    </a>
  `,
})
export class App {
  mySignal$: WritableSignal<{ msg: string } | undefined> = signal(undefined);

  constructor() {
    this.mySignal$.set({ msg: 'Hello there!' });

    effect(() => {
      if (this.mySignal$()) {
        // console.info(this.mySignal$()!.msg); // or this
        console.info(this.mySignal$()?.msg); // Object is possibly 'undefined'.ts(2532)

        // Works but feels like there should be an easier way
        // console.info((this.mySignal$() as { msg: string }).msg)
      }
    });
  }
}

bootstrapApplication(App);

Демо-версия Stackblitz

Спасибо, я воспользуюсь Not Null Assertion. Ранее я отключил его в своем .eslint.json, так как считал, что это плохая практика. Но это похоже на реальный вариант использования. Мой код, не являющийся примером, имел немного более сложный вариант использования, который лучше подходил для этого, я слишком сильно упростил его для своего примера.

Filip Strandberg 30.05.2024 09:21

Другие вопросы по теме