Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type '{ visibility: string; 'line-join': string; 'line-cap': string; } | { visibility: string; }' is not assignable to type

I am using mapbox with angular. And I try to show/hide some stuff with mapbox.

So I have this component:

export class ToggleLayersComponent implements OnInit {
  layouts = {
    contours: {
      visibility: 'visible',
      'line-join': 'round',
      'line-cap': 'round',
    },
    museums: {
      visibility: 'visible',
    },
  };

  ngOnInit() {}

  toggleLayer(evt: {value: 'contours' | 'museums'}) {
    this.layouts[evt.value] = {
      ...this.layouts[evt.value],
      visibility: this.layouts[evt.value].visibility === 'visible' ? 'none' : 'visible',
    };
  }
}

But I get this error:

Type '{ visibility: string; 'line-join': string; 'line-cap': string; } | { visibility: string; }' is not assignable to type '{ visibility: string; 'line-join': string; 'line-cap': string; } & { visibility: string; }'.
  Type '{ visibility: string; }' is not assignable to type '{ visibility: string; 'line-join': string; 'line-cap': string; } & { visibility: string; }'.
    Type '{ visibility: string; }' is missing the following properties from type '{ visibility: string; 'line-join': string;

Of course I googled first. But I can't find any solution.

So how to fix this?

Thank you

So the error is on this line:

 this.layouts[evt.value] 

So I can't even run Angular anymore:

ERROR in src/app/desktop-dashboard/toggle-layer/toggle-layer.component.ts:63:5 - error TS2322: Type '{ visibility: string; 'line-join': string; 'line-cap': string; } | { visibility: string; }' is not assignable to type '{ visibility: string; 'line-join': string; 'line-cap': string; } & { visibility: string; }'.    
  Type '{ visibility: string; }' is not assignable to type '{ visibility: string; 'line-join': string; 'line-cap': string; } & { visibility: string; }'.      
    Type '{ visibility: string; }' is missing the following properties from type '{ visibility: string; 'line-join': string; 'line-cap': string; }': 'line-join', 'line-cap'

63     this.layouts[evt.value] = {
like image 565
mightycode Newton Avatar asked May 17 '26 15:05

mightycode Newton


1 Answers

The TypeScript compiler is not "smart" enough at this point. When you do:

this.layouts[evt.value] = {
  ...this.layouts[evt.value]
}

It sees the evt.value as type 'contours' | 'museums', and it cannot infer that it twice is the same value, and twice will be the same object. Basically it's preventing you from doing:

this.layouts['contours'] = {
  ...this.layouts['museums']
}

In your example, you can do the following

this.layouts[evt.value].visibility = this.layouts[evt.value].visibility === 'visible'
  ? 'none'
  : 'visible';

But I suppose you do not want to do it this way, because change detection might not see that the object reference has changed. If that's an issue for you, I see no other way than to trick the compiler:

toggleLayer(evt: {value: 'contours' | 'museums'}) {
  const key = evt.value as 'contours';

  this.layouts[key] = {
    ...this.layouts[key],
    visibility: this.layouts[key].visibility === 'visible' ? 'none' : 'visible'
  };
}
like image 179
Poul Kruijt Avatar answered May 19 '26 05:05

Poul Kruijt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!