Skip to content

Commit

Permalink
refactor(writer): pass generics to $Props
Browse files Browse the repository at this point in the history
  • Loading branch information
metonym committed Oct 27, 2024
1 parent 7d8c16f commit 87f926f
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/writer/writer-ts-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ function genPropDef(def: Pick<ComponentDocApi, "props" | "rest_props" | "moduleN

prop_def = `
${extend_tag_map ? `type RestProps = ${extend_tag_map};\n` : ""}
type $Props = {
type $Props${genericsName} = {
${props}
${dataAttributes}
};
export type ${props_name}${genericsName} = Omit<RestProps, keyof $Props> & $Props;
export type ${props_name}${genericsName} = Omit<RestProps, keyof $Props${genericsName}> & $Props${genericsName};
`;
} else {
prop_def = `
Expand Down
105 changes: 105 additions & 0 deletions tests/__snapshots__/fixtures.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,69 @@ exports[`fixtures (JSON) "typedefs/input.svelte" 1`] = `
}"
`;

exports[`fixtures (JSON) "generics-with-rest-props/input.svelte" 1`] = `
"{
"props": [
{
"name": "headers",
"kind": "let",
"type": "ReadonlyArray<DataTableHeader<Row>>",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
},
{
"name": "rows",
"kind": "let",
"type": "ReadonlyArray<Row>",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
}
],
"moduleExports": [],
"slots": [
{
"name": "__default__",
"default": true,
"slot_props": "{ headers: ReadonlyArray<DataTableHeader<Row>>, rows: ReadonlyArray<Row> }"
}
],
"events": [],
"typedefs": [
{
"type": "{ id: string | number; [key: string]: any; }",
"name": "DataTableRow",
"ts": "interface DataTableRow { id: string | number; [key: string]: any; }"
},
{
"type": "Exclude<keyof Row, \"id\">",
"name": "DataTableKey<Row>",
"ts": "type DataTableKey<Row> = Exclude<keyof Row, \"id\">"
},
{
"type": "{ key: DataTableKey<Row>; value: string; }",
"name": "DataTableHeader<Row=DataTableRow>",
"ts": "interface DataTableHeader<Row=DataTableRow> { key: DataTableKey<Row>; value: string; }"
}
],
"generics": [
"Row",
"Row extends DataTableRow = DataTableRow"
],
"rest_props": {
"type": "Element",
"name": "div"
}
}"
`;

exports[`fixtures (JSON) "bind-this/input.svelte" 1`] = `
"{
"props": [
Expand Down Expand Up @@ -1518,6 +1581,48 @@ export default class Typedefs extends SvelteComponentTyped<
"
`;
exports[`fixtures (TypeScript) "generics-with-rest-props/input.svelte" 1`] = `
"import type { SvelteComponentTyped } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";
export interface DataTableRow {
id: string | number;
[key: string]: any;
}
export type DataTableKey<Row> = Exclude<keyof Row, "id">;
export interface DataTableHeader<Row = DataTableRow> {
key: DataTableKey<Row>;
value: string;
}
type RestProps = SvelteHTMLElements["div"];
type $Props<Row> = {
/**
* @default []
*/
headers?: ReadonlyArray<DataTableHeader<Row>>;
/**
* @default []
*/
rows?: ReadonlyArray<Row>;
[key: \`data-${string}\`]: any;
};
export type GenericsWithRestPropsProps<Row> = Omit<RestProps, keyof $Props<Row>> & $Props<Row>;
export default class GenericsWithRestProps<Row extends DataTableRow = DataTableRow> extends SvelteComponentTyped<
GenericsWithRestPropsProps<Row>,
Record<string, any>,
{ default: { headers: ReadonlyArray<DataTableHeader<Row>>; rows: ReadonlyArray<Row> } }
> {}
"
`;
exports[`fixtures (TypeScript) "bind-this/input.svelte" 1`] = `
"import type { SvelteComponentTyped } from "svelte";
Expand Down
5 changes: 3 additions & 2 deletions tests/e2e/carbon/types/DataTable/DataTable.svelte.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export interface DataTableCell {

type RestProps = SvelteHTMLElements["div"];

type $Props = {
type $Props<Row> = {
/**
* Specify the data table headers
* @default []
Expand Down Expand Up @@ -183,7 +183,8 @@ type $Props = {
[key: `data-${string}`]: any;
};

export type DataTableProps<Row> = Omit<RestProps, keyof $Props> & $Props;
export type DataTableProps<Row> = Omit<RestProps, keyof $Props<Row>> &
$Props<Row>;

export default class DataTable<
Row extends DataTableRow = DataTableRow
Expand Down
50 changes: 50 additions & 0 deletions tests/fixtures/generics-with-rest-props/Test.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script lang="ts">
import Generics, { type DataTableHeader } from "./output";
const headers: DataTableHeader<{ name: string; port: number }>[] = [
{
key: "name",
value: "Name",
},
{
key: "port",
value: "Port",
},
];
const rows = [
{ id: 1, name: "Name 1", port: 3000 },
{ id: 2, name: "Name 2", port: 3000 },
{ id: 3, name: "Name 3", port: 3000 },
] as const;
</script>

<Generics {headers} {rows} let:rows>
{#each rows as row}
{row.name}
{row.port}
{/each}
</Generics>

<Generics
headers={[
{
key: "name",
value: "Name",
},
{
key: "port",
value: "Port",
},
]}
rows={[
{ id: 1, name: "Name 1", port: 3000 },
{ id: 2, name: "Name 2", port: 3000 },
{ id: 3, name: "Name 3", port: 3000 },
]}
let:rows
>
{#each rows as row}
{row.name}
{/each}
</Generics>
19 changes: 19 additions & 0 deletions tests/fixtures/generics-with-rest-props/input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<script>
/**}
* @typedef {{ id: string | number; [key: string]: any; }} DataTableRow
* @typedef {Exclude<keyof Row, "id">} DataTableKey<Row>
* @typedef {{ key: DataTableKey<Row>; value: string; }} DataTableHeader<Row=DataTableRow>
* @template {DataTableRow} <Row extends DataTableRow = DataTableRow>
* @generics {Row extends DataTableRow = DataTableRow} Row
*/
/** @type {ReadonlyArray<DataTableHeader<Row>>} */
export let headers = [];
/** @type {ReadonlyArray<Row>} */
export let rows = [];
</script>

<div {...$$restProps}>
<slot {headers} {rows} />
</div>
38 changes: 38 additions & 0 deletions tests/fixtures/generics-with-rest-props/output.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { SvelteComponentTyped } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";

export interface DataTableRow {
id: string | number;
[key: string]: any;
}

export type DataTableKey<Row> = Exclude<keyof Row, "id">;

export interface DataTableHeader<Row = DataTableRow> {
key: DataTableKey<Row>;
value: string;
}

type RestProps = SvelteHTMLElements["div"];

type $Props<Row> = {
/**
* @default []
*/
headers?: ReadonlyArray<DataTableHeader<Row>>;

/**
* @default []
*/
rows?: ReadonlyArray<Row>;

[key: `data-${string}`]: any;
};

export type GenericsWithRestPropsProps<Row> = Omit<RestProps, keyof $Props<Row>> & $Props<Row>;

export default class GenericsWithRestProps<Row extends DataTableRow = DataTableRow> extends SvelteComponentTyped<
GenericsWithRestPropsProps<Row>,
Record<string, any>,
{ default: { headers: ReadonlyArray<DataTableHeader<Row>>; rows: ReadonlyArray<Row> } }
> {}
60 changes: 60 additions & 0 deletions tests/fixtures/generics-with-rest-props/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"props": [
{
"name": "headers",
"kind": "let",
"type": "ReadonlyArray<DataTableHeader<Row>>",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
},
{
"name": "rows",
"kind": "let",
"type": "ReadonlyArray<Row>",
"value": "[]",
"isFunction": false,
"isFunctionDeclaration": false,
"isRequired": false,
"constant": false,
"reactive": false
}
],
"moduleExports": [],
"slots": [
{
"name": "__default__",
"default": true,
"slot_props": "{ headers: ReadonlyArray<DataTableHeader<Row>>, rows: ReadonlyArray<Row> }"
}
],
"events": [],
"typedefs": [
{
"type": "{ id: string | number; [key: string]: any; }",
"name": "DataTableRow",
"ts": "interface DataTableRow { id: string | number; [key: string]: any; }"
},
{
"type": "Exclude<keyof Row, \"id\">",
"name": "DataTableKey<Row>",
"ts": "type DataTableKey<Row> = Exclude<keyof Row, \"id\">"
},
{
"type": "{ key: DataTableKey<Row>; value: string; }",
"name": "DataTableHeader<Row=DataTableRow>",
"ts": "interface DataTableHeader<Row=DataTableRow> { key: DataTableKey<Row>; value: string; }"
}
],
"generics": [
"Row",
"Row extends DataTableRow = DataTableRow"
],
"rest_props": {
"type": "Element",
"name": "div"
}
}

0 comments on commit 87f926f

Please sign in to comment.