Different node properties for different labels in GDS Cypher projection

I create a graph for Neo4j GDS algorithms using Cypher projection approach. The graph is bi-parity graph with two types of nodes with different labels. Each node type has its own structure of nodes properties. How to node query for this case should look like? This is clear for native projection - example is in the documentation.
For Cypher projection the documentation suggests the following node query:

'MATCH (n) WHERE n:Author OR n:Article OR n:Book RETURN id(n) AS id, labels(n) AS labels'.

Another approach I've found is to use UNION clause:

'MATCH (n:Person) RETURN id(n) AS id
MATCH (n:Thing) RETURN id(n) as id'

But both solutions do not allow to define separate sets of properties (UNION clause requires the same set of returning variables for all sub-queries).
So my question is how to arrange defining different properties for different labels in Cypher projection approach to create graphs for GDS?

How specific are the properties you are looking to use? For example, in the case of a:Article or b:Book, suppose you had specific properties that were exact, like a.publication_year = 2021 and b.publication_year = 2020 (just making this up). Is that what you mean by "defining a separate set of properties?" Or would these properties be something like a range (a.publication_date < 2021)?

Suppose for books we have ISBN number, title, and number of pages. For articles we need journal title and volume number. So properties of different types may be completely different (by number, by type).

Cypher projections are intended for simple experimentation - reshaping your graph for specific purposes; I don't think they'll let you load multiple node labels with different properties for different labels. If you want to load different types of nodes, with different properties, you're better off using a native projection and pathCollapse or the subgraph projections if you want to modify your graph architecture.

You could try something like:

CALL gds.graph.create{
  {Person: {
            age:{property:'age', defaultValue:0},
            score:{property:'score', defaultValue:0}
   Thing: {
            size:{property:'size', defaultValue:0},
            number:{property:'count', defaultValue:0}
  {HAS: {
     aggregation: 'COUNT'

(hopefully my curly braces are correct, but you get the idea)

If you want to connect - for example - people who have the same item, you can use collapsePath on the projected graph. If you'd like to filter the graph based on a property, as of 1.6, you can use a subgraph projection.