Redux Toolkit TS: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'WritableDraft<configSlice>' - redux-toolkit

I have a common dispatcher to update multiple states as shown below:
updateConfiguration: (state, action) => {
const { type, payload } = action.payload
const { dispatchKey, stateKey } = keyHelpers[type as keyof keyHelpersType]
state[stateKey] = payload[dispatchKey]
}
where keyHelpers is as shown below:
export const keyHelpers: keyHelpersType = {
[actionTypes.addUser]: {
dispatchKey: 'user',
stateKey: 'user',
}
When writing the dispatch logic in my reducer I am getting the following error in following line:
state[stateKey] = payload[dispatchKey]
Error:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'WritableDraft<configSlice>'
I tried doing:
state[stateKey as keyof typeof state] = payload[dispatchKey]
but this didn't work as well throwing:
Type 'any' is not assignable to type 'never'.ts(2322)
Can someone help me resolve this?

You probably have to add an as const assertion:
export const keyHelpers: keyHelpersType = {
[actionTypes.addUser]: {
dispatchKey: 'user',
stateKey: 'user',
}
} as const
That way it will not be string, but "user".

Related

Ag Grid Row Style [getRowStyle]="getRowStyle" geting error as param implicit has an any

I'm using ag-grid as
<ag-grid-angular [rowStyle]="rowStyle" [getRowStyle]="getRowStyle"
</ag-grid-angular>
Angular code as
pubic export class Testingcomponent {
getRowStyle = function(params) {
if (params.node.rowIndex % 2 === 0) {
return { background: 'red' };
}
};
...
}
at param i'm getting error as parameter 'params' implicitly has an 'any' type
i'm trying for getting alternate row colour but as per the documentation [getRowStyle]="getRowStyle" we are passing any parameter & i'm getting error as param
You need to provide a type for params.
Solution 1 -
getRowStyle = function(params:any) { ...}
Solution 2 -
import { RowClassParams } from 'ag-grid-community';
getRowStyle: (params: RowClassParams) => { ... }

Cant use flutter DateTime in ferry query

Here is the query
query UpcomingPendingEvents($attendantId: ID, $eventDateTimeGt: DateTime) {
attendances(attendant_Id: $attendantId, attending: "0",
event_Datetime_Gt: $eventDateTimeGt, first: 10,) {
# some fields here
}
}
I get the error A value of type 'DateTime' can't be assigned to a variable of type 'GDateTimeBuilder?' when I use the following query
gqlClient.request(GUpcomingPendingEventsReq(
(b) => b
..vars.attendantId = attendantId
..vars.eventDateTimeGt = DateTime.parse('2021-12-15T17:00:00'),
));
And when I try to use it like that.
gqlClient.request(GUpcomingPendingEventsReq(
(b) => b
..vars.attendantId = attendantId
..vars.eventDateTimeGt = DateTime.parse('2021-12-15T17:00:00') as GDateTimeBuilder?,
));
I get runtime error
type 'DateTime' is not a subtype of type 'GDateTimeBuilder?' in type cast.
I think you need to assign it to the value on the GDateTimeBuilder.
...
(b) => b
..vars.attendantId = attendantId
..vars.eventDateTimeGt.value = '2021-12-15T17:00:00' // <-- here
...

Need working example of a custom Sequelize Postgres datatype

I have a custom type in Postgres that I want to use in Sequelize. I've written code based on the example in the Sequelize docs, except for call to a function ("inherits") which I can't find in Sequelize or elsewhere. However, using sequelize.define to create a model with an attribute of this custom type throws an exception inside Sequelize. Is there an error in my code that stands out? Or is there another good example or tutorial for implementing a custom datatype? Also, what's up with the "inherits" function shown in the doc example -- are the docs leaving out an import/requires, or is that call erroneous?
Docs I'm following are here: http://docs.sequelizejs.com/manual/data-types.html#extending-datatypes
The type as defined in Postgres:
CREATE TYPE public.measurement AS
(
unit text,
value double precision
);
My test code in NodeJS:
const Sequelize = require('sequelize');
let dataTypes = Sequelize.DataTypes;
// Create class for custom datatype
class MEASUREMENT extends dataTypes.ABSTRACT {
toSql() {
console.log('MEASUREMENT toSql');
return 'MEASUREMENT';
}
static parse(value) {
console.log('MEASUREMENT parse value=', value);
return value;
}
};
// Set key
MEASUREMENT.prototype.key = 'MEASUREMENT';
MEASUREMENT.key = MEASUREMENT.prototype.key;
// Add to DataTypes
dataTypes.MEASUREMENT = MEASUREMENT;
// Add to Sequelize
Sequelize.MEASUREMENT = Sequelize.Utils.classToInvokable(MEASUREMENT);
let pgTypes = dataTypes.postgres;
// Map dialects
dataTypes.MEASUREMENT.types.postgres = ['MEASUREMENT']
pgTypes.MEASUREMENT = function MEASUREMENT() {
if (!(this instanceof pgTypes.MEASUREMENT)) return new pgTypes.MEASUREMENT();
DataTypes.MEASUREMENT.apply(this, arguments);
}
// inherits(pgTypes.MEASUREMENT, dataTypes.MEASUREMENT);
// Node throws a parse error. This is in the example in the Sequelize docs, however.
pgTypes.MEASUREMENT.parse = dataTypes.MEASUREMENT.parse;
// ------------------------------
const sequelize = new Sequelize('test', 'test', 'test', {
host: 'localhost',
dialect: 'postgres'
});
const Thing = sequelize.define('thing', {
name: Sequelize.STRING,
weight: Sequelize.MEASUREMENT
});
Call stack when run:
C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:48
if (dataType.types[this.dialectName]) {
^
TypeError: Cannot read property 'postgres' of undefined
at _.each.dataType (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:48:27)
at C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:4911:15
at baseForOwn (C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:2996:24)
at C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:4880:18
at Function.forEach (C:\Workspaces\nebula\server\node_modules\lodash\lodash.js:9344:14)
at ConnectionManager.refreshTypeParser (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\abstract\connection-manager.js:46:7)
at new ConnectionManager (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\postgres\connection-manager.js:23:10)
at new PostgresDialect (C:\Workspaces\nebula\server\node_modules\sequelize\lib\dialects\postgres\index.js:14:30)
at new Sequelize (C:\Workspaces\nebula\server\node_modules\sequelize\lib\sequelize.js:320:20)
at Object.<anonymous> (C:\Workspaces\nebula\server\testsequelizecustom.js:58:19)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:279:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:752:3)
To fix the error, we need to cause the property postgres on the object dataType.types to be defined.
Just under the line you already have:
pgTypes.MEASUREMENT.parse = dataTypes.MEASUREMENT.parse;
Add the following line, and the error should go away:
pgTypes.MEASUREMENT.types = {postgres:[‘MEASUREMENT’]};
You'll probably also need to add this line, to handle a related error (see below).
dataTypes.postgres.MEASUREMENT.key = ‘MEASUREMENT’;
The related error:
[...]/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:36
if (dataType.key.toLowerCase() === 'range') {
^
TypeError: Cannot read property 'toLowerCase' of undefined

How to solve TS2349 in a protractor test model

I've got the following test setup, but the transpiler is giving me the following error:
Error:(108, 9) TS2349:Cannot invoke an expression whose type lacks a call signature. Type '((opt_callback?: (value: Model1[]) => R | IThenable, opt_errback?: (error: any...' has no compatible call signatures.
// action class
export class SearchResultsActions {
// setup and other stuff
// Model1 and Model2 are both interfaces
getJSON(): promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>> {
return option.getText().then((selected: string) => {
let searchType: "model1" | "model2" = "model1";
if (selected === "Model 2") {
searchType = "model2";
}
// getResultsEl returns an ElementArrayFinder
return ResultsPage.getResultsEl().map((el, index) => {
let pageObject: Model1PageObject | Model2PageObject = SearchPage.getResult(searchType, index);
let actionObject: Model1Actions | Model2Actions;
if (searchType === "model1") {
actionObject = new Model1Actions(<Model1PageObject> pageObject);
} else {
actionObject = new Model2Actions(<Model2PageObject> pageObject)
}
// both Model1Actions and Model2Actions have a getJSON() method
return actionObject.getJSON(); // returns a JSON object
});
});
}
}
In the search spec where the error is:
SearchResultsActions.getJSON()
.then((res: Array<Model1> | Array<Model2>) => {
// use lodash to perform equality
expect(_.isEqual(res, expected)).toBeTruthy();
});
The curious thing is, despite the error, the transpile works anyway and the tests pass. But I would like to not have the error blaring at me.
I'm using typescript 2.3.3, protractor 5.1.2
Any thoughts? Anywhere I can clarify?
The answer is to change the return type to
promise.Promise<Array<Model1> | Array<Model2>>
which is different from
promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>>
which doesn't work.
Apparently this is true for Observables as well.

How to replace function name with a babel plugin

Is it possible to create a babel plugin that will change some a functions name ?
I can't seems to find this in the documentation.
Example:
myObject.doSomething() ==> babel ==> myObject.___doSomething()
Thanks
You can get the AST of your code in astexplorer. And you can see it's about a CallExpression and MemberExpression. So search babel-types API in babel-types source code, it's very clear of how to create a babel type or judge a babel-type like this:
defineType("MemberExpression", {
builder: ["object", "property", "computed"],
visitor: ["object", "property"],
aliases: ["Expression", "LVal"],
fields: {
object: {
validate: assertNodeType("Expression")
},
property: {
validate(node, key, val) {
let expectedType = node.computed ? "Expression" : "Identifier";
assertNodeType(expectedType)(node, key, val);
}
},
computed: {
default: false
}
}
});
Following are two different ways to do it (either with the Program visitor or with the FunctionDeclaration visitor):
export default function ({types: t}) {
return {
visitor: {
Program(path) {
path.scope.rename('doSomething', '___doSomething');
},
FunctionDeclaration(path) {
if (path.node.id.name === 'doSomething') {
path.node.id.name = '___doSomething'
}
}
}
};
}
Note that these are not safe since they can override an existing name. You can use the path.scope.generateUidIdentifier("uid"); command to generate a unique identifier and use that but you wont be able to define the generated name.
Example - http://astexplorer.net/#/o5NsNwV46z/1