Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VectorLayerOptions does not use the same generic type as VectorLayer #15837

Closed
KyllianGautier opened this issue May 17, 2024 · 11 comments · Fixed by #15843
Closed

VectorLayerOptions does not use the same generic type as VectorLayer #15837

KyllianGautier opened this issue May 17, 2024 · 11 comments · Fixed by #15843
Labels

Comments

@KyllianGautier
Copy link

KyllianGautier commented May 17, 2024

Describe the bug
VectorLayerOptions does not have the same generic type as VectorLayer
image
image

To Reproduce
Use a VectorLayer by instantiate it with a VectorLayerOptions:
(options?: OLVectorLayerOptions<OLFeatureLike>) => new OLVectorLayer<OLFeatureLike>(options)
See that the required types are not the same since the v9.2.1.
Before the v9.2.0, the types were both VectorSource.

Expected behavior
We can instantiate a VectorLayer with an Option object that uses the same required generic type as VectorLayer.
Such as ClusterLayer and ClusterLayerOptions for example

@ahocevar
Copy link
Member

ahocevar commented May 17, 2024

@KyllianGautier The type of the Options has to include the source, because the options are used for several BaseVector layer subclasses. For the VectorLayer, the source type is determined and does not require generics for the source. Does this cause a real-life problem?

@KyllianGautier
Copy link
Author

KyllianGautier commented May 17, 2024

@ahocevar Ok, I understand. I tryed to adapt, but I still have some very strange problems with the typing :
Here I created a factory to instantiate a VectorLayer:
image
(I prefix all Openlayers object by "OL" in my imports, I hope you can understand easily)

@ahocevar
Copy link
Member

Maybe you got some of the imports wrong? This works fine for me:

import { FeatureLike as OLFeatureLike } from 'ol/Feature.js';
import { Options as OLBaseVectorLayerOptions } from 'ol/layer/BaseVector.js';
import OLVectorLayer from 'ol/layer/Vector.js';
import OLVectorSource from 'ol/source/Vector.js';

export const vectorLayer = <F extends OLFeatureLike>(options?: OLBaseVectorLayerOptions<OLVectorSource<F>>) => new OLVectorLayer<F>(options);

@KyllianGautier
Copy link
Author

KyllianGautier commented May 17, 2024

@ahocevar Unfortunately, I have errors in typescript trying your solution:
image
But this works fine in javascript indeed

@ahocevar
Copy link
Member

Thanks @KyllianGautier, you are right. In #15843 I made it so the options and the layer have the same generics again - both the FeatureType, no longer SourceType<FeatureType>.

@KyllianGautier
Copy link
Author

KyllianGautier commented May 21, 2024

@ahocevar thanks for this fix. I still have issue with typing in typescript :'(
I am able to give a TileLayer<TileSource> as a Layer<Source, Renderer>.
But I can't give a VectorLayer<FeatureLike> as a Layer<Source, Renderer>.

image

I'm sorry to disturbing you, but I don't find solution, and I don't know how to get the info to understand if I'm doing something wrong.

You can test a simple example of the typing problem in Typescript:

image

@ahocevar
Copy link
Member

ahocevar commented May 21, 2024

I am able to give a TileLayer as a Layer<Source, Renderer>.

Yes, but you don't need to specify the Renderer type. And other than the Vector and VectorTile sources, TypeScript needs to distinguish between the different ol/layer/Tile subclasses here, because subclasses have additional API methods.

But I can't give a VectorLayer as a Layer<Source, Renderer>.

Correct, that's no longer the type signature.

You can test a simple example of the typing problem in Typescript:
export const vectorLayer: OLVectorLayer<OLFeatureLike> = new OLVectorLayer<OLFeature>();

That's also expected. There is no inheritance relationship between the allowed types of FeatureLike. Feature and RenderFeature only have a small subset of a common API. So in TypeScript, you have to decide when you declare the variable what you're going to store there. When using JavaScript, the correct type will be inferred. The following will work in TypeScript:

export const vectorLayer: OLVectorLayer<OLFeature> = new OLVectorLayer<OLFeature>();

@KyllianGautier
Copy link
Author

KyllianGautier commented May 22, 2024

Thanks for the details. I tried what you proposed, and I still have issues in Typescript:

image
image

And I tried to change the type of for options and source:

image
image

@ahocevar
Copy link
Member

ahocevar commented May 22, 2024

@KyllianGautier You're still using the old type signature for the options. This should now be:

import { Feature as OLFeature } from 'ol';
import OLVectorLayer, { Options as OLVectorLayerOptions } from 'ol/layer/Vector.js';
import OLVectorSource from 'ol/source/Vector.js';

const options: OLVectorLayerOptions<OLFeature> = {
  source: new OLVectorSource<OLFeature>()
};

export const layer = new OLVectorLayer(options);

@KyllianGautier
Copy link
Author

KyllianGautier commented May 23, 2024

@ahocevar Ok, problem solved, thanks for the support.

I have an additional question about the Layer.getSource() method. How can we type the source returned by a VectorLayer ?

If I use a Custer source for example, I instantiate a VectorLayer with this Cluster source, and i'm not able to use the Cluster source specific methods such as setDistance() or setMinDistance():

image

Other side effect, it seems that a VectorLayer with an other source than a Vector source is not assiciable with a Layer ?

image

@ahocevar
Copy link
Member

In #15869, the source type is added back as 2nd type parameter to vector and vectortile layers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants