I'm trying to define an AsycIterator and use it. Defining works but using it has been a problem. This is the code I have, please note that other code not related to the question has been removed
This is how I define the iterator
export interface IDriver {
tables(): AsyncIterator<Table>
// code removed
}
This is how I implement it.
export class MySql implements IDriver {
async *tables(): AsyncIterator<Table> {
const sql = `select table_name, table_type, table_rows
from information_schema.tables
where table_schema = ${this.schema}
order by table_name;`
const rows = await this.query<{
table_name: string
table_type: string
table_rows: number
}>(sql)
for (const row of rows) {
yield {
name: row.table_name,
rows: row.table_rows,
type: row.table_type
} as Table
}
}
// ---
}
This is my package.json file
{
"compilerOptions": {
"target": "ESNext" ,
"lib": [
"ES2018.AsyncIterable",
"DOM",
"ESNext"
] ,
"jsx": "preserve" ,
"experimentalDecorators": true ,
"emitDecoratorMetadata": true ,
"useDefineForClassFields": true ,
"moduleDetection": "auto" ,
"module": "NodeNext",
"rootDir": "src/" ,
"moduleResolution": "NodeNext" ,
"allowUmdGlobalAccess": true ,
"resolvePackageJsonExports": true ,
"resolvePackageJsonImports": true ,
"resolveJsonModule": true ,
"checkJs": true ,
"declaration": true ,
"declarationMap": true ,
"sourceMap": true ,
"outDir": "./build" ,
"removeComments": true ,
"newLine": "crlf" ,
"stripInternal": true ,
"preserveConstEnums": true ,
"allowSyntheticDefaultImports": true ,
"esModuleInterop": true ,
"forceConsistentCasingInFileNames": true ,
"strict": true ,
"noImplicitAny": true ,
"strictNullChecks": true ,
"strictFunctionTypes": true ,
"strictBindCallApply": true ,
"strictPropertyInitialization": true ,
"noImplicitThis": true ,
"useUnknownInCatchVariables": true ,
"alwaysStrict": true ,
"noUnusedLocals": true ,
"noUnusedParameters": true ,
"exactOptionalPropertyTypes": true ,
"noImplicitReturns": true ,
"noFallthroughCasesInSwitch": true ,
"noUncheckedIndexedAccess": true ,
"noImplicitOverride": true ,
"noPropertyAccessFromIndexSignature": true ,
"skipLibCheck": true ,
},
"include": ["./src/*"]
}
This is the usage of the above function
for await (const it of mysql.tables()) {
print(it)
}
which gives me a an error
src/main.ts:13:26 - error TS2504: Type 'AsyncIterator<Table, any, undefined>' must have a [Symbol.asyncIterator] () method that returns an async iterator.
If I try to explore it, this is what I find in type definitions:
interface AsyncIterable<T> {
[Symbol.asyncIterator](): AsyncIterator<T>;
}
interface SymbolConstructor {
/**
* A method that returns the default async iterator for an object. Called by the semantics of
* the for-await-of statement.
*/
readonly asyncIterator: unique symbol;
}
declare var Symbol: SymbolConstructor;
I also tried this solution given here:
It is a 6 year old question as of now and does not work at all in my case. core-js/shim has no effect. I don't know if the solution was only valid for a particular version of typecript. I'm using Version 5.5.4. the only way I'm able to use AsyncIterator is given below.
const rows = await mysql.tables()
let item = await rows.next()
while (!item.done) {
item = await rows.next()
}
Which obviously is a weird way to use AsyncIterator, Really if this is the solution then perhaps not using AsyncIterator is the best option
Does anyone know what changes are required to make the code for await () work or Do i need to change my code?
Please note that I cannot return an array of my dataset because line by line processing is really needed.