Element implicitly has an 'any' type because expression of type 'string' can't be used to index type in Angular - TagMerge
4Element implicitly has an 'any' type because expression of type 'string' can't be used to index type in AngularElement implicitly has an 'any' type because expression of type 'string' can't be used to index type in Angular

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type in Angular

Asked 1 years ago
1
4 answers

The problem is that your reduce callback is expecting an object that comply with the ICar interface which is true only in the first iteration, on the next iteration of the reduce callback, you won't receive anymore an object of ICar type (only IDetails or string), so the constraint fails. Basically, the return of every iteration return a different type and that's why you cannot use a specific type there, you could use a union of types in some cases though.

To fix your issue, just replace the ICar type to any, like below. I don't see any issue with this because you are still type checking the getCarProperty function parameters.

getCarProperty = (obj: ICar, path: string): any => {
    if (path.indexOf('.') > -1) {
      return path.split('.').reduce((o: any, p: string) => {
        return o && o[p];
      }, obj);
    }

    return Array.of(path).reduce((o: any, p: string) => {
      return o && o[p];
    }, obj);
};

If you really want to preserve the types, and you don't want to use any, you could try the function below, but I don't see much advantage since you are already typing your function parameters.

function getCarProperty(obj: ICar, path: string): any {
  type CarOrDetailType = ICar | IDetail; // <-- All the possibilities for the reduce `previousValue` callback parameter. If the ICar interface changes, you might need to adjust this.
  type CarOrDetailKey = keyof CarOrDetailType;

  if (path.indexOf('.') > -1) {
    const typedPath = path.split('.') as Array<CarOrDetailKey>;
    return typedPath.reduce((o: CarOrDetailType, p: CarOrDetailKey): any => {
      return o && o[p];
    }, obj);
  }

  const typedPath = Array.of(path) as Array<CarOrDetailKey>;
  return typedPath.reduce((o: CarOrDetailType, p: CarOrDetailKey) => {
    return o && o[p];
  }, obj);
}

Two more issues that I found with your code, but it could have been that you miscopied, are:

  • Your mock data don't have comas after every property, so it has not a valid syntax.
  • You used Array.from(path) on a string, but you probably wanted Array.of(path).

Source: link

0

Solution 1
items: object[],
While technically it is a JavaScript object, the type can be better. For Typescript to correctly help you identify mistakes when accessing objects properties, you need to tell it the exact shape of the object. If you type it as object, typescript cannot help you with that. Instead, you could tell it the exact properties and datatypes the object has:
let assistance: { safe: string } = { safe: 1 /* typescript can now tell this is wrong */ };
  assistance.unknown; // typescript can tell this wont really work too
Now in the case that the object can contain any sort of key/value pair, you can at least tell typescript what type the values (and the keys) have, by using an object index type:
items: {
   [key: string]: number | string,
  }[]
If it’s a pedantic javascript object that doesn’t make sense to create type definitions per field for and doesn’t make sense as a class definition, you can type the object with and typescript will let you index however you want. Example.
//obviously no one with two brain cells is going to type each field individually
let complicatedObject: any = {
    attr1: 0,
    attr2: 0,
    ...
    attr999: 0
}

Object.keys(complicatedObject).forEach(key => {
    complicatedObject[key] += 1;
}
First of all, defining the type of items as an array of objects is a bad idea, as it defeats the purpose of Typescript. Instead, define what type of objects the array will contain. I would do it this way:
type Item = {
  id: number,
  name: string,
  email: string,
}

export type TableGridViewProps = {
  items: Item[],
  tableColumns: TableColumn[]
};

Source: link

0

Code
import Sequelize from 'sequelize';
import { DbInterface } from'typings/DbInterface';
import { UserFactory } from './User';
import { PostFactory } from './Post';
import { CommentFactory } from './Comment';

export const createModels = (sequelizeConfig: any): DbInterface => {
  const { database, username, password, params } = sequelizeConfig;
  const sequelize = new Sequelize(database, username, password, params);

  const db: DbInterface = {
    sequelize,
    Sequelize,
    Comment: CommentFactory(sequelize, Sequelize),
    Post: PostFactory(sequelize, Sequelize),
    User: UserFactory(sequelize, Sequelize)
  };

  Object.keys(db).forEach(modelName => {
    if (db[modelName].associate) { //Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'DbInterface'. No index signature with a parameter of type 'string' was found on type 'DbInterface'.
      db[modelName].associate(db); //Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'DbInterface'. No index signature with a parameter of type 'string' was found on type 'DbInterface'.
    }
  });

  return db;
};
// bad
const _getKeyValue = (key: string) => (obj: object) => obj[key];

// better
const _getKeyValue_ = (key: string) => (obj: Record<string, any>) => obj[key];

// best
const getKeyValue = <T extends object, U extends keyof T>(key: U) => (obj: T) =>
  obj[key];
@alexandermckay What if I have this scenario:
type props = {
  type: string
}

const style = styles[props.type]

const styles = StyleSheet.create({
  base: {
    ...spacing.medium,
    padding: 10,
    textAlign: "center",
    textAlignVertical: "center",
    fontWeight: "bold",
    fontSize: 18,
    height: 50,
  },
  primary: {
    backgroundColor: colors.purple,
    color: colors.white,
  },
  secondary: {
    backgroundColor: "transparent",
    color: colors.purple,
    borderColor: colors.purple,
    borderWidth: 2,
  },
}
Same question here, I have
const LEVEL_DEBUG = 1;
const LEVEL_FINE = 2;

const LOG_LEVELS = {
  info: LEVEL_INFO,
  debug: LEVEL_DEBUG,
  fine: LEVEL_FINE,
};

let logLevel: string = environment.logLevel;
if (!logLevel) {
  logLevel = 'info';
}
let _level = LOG_LEVELS[logLevel.toLowerCase()]; // here it complains
@greenlaw110 Try to get the key value by using @alexandermckay's method:
const LEVEL_DEBUG = 1;
const LEVEL_FINE = 2;


const LOG_LEVELS: {[key:string]: number} = {
  debug: LEVEL_DEBUG,
  fine: LEVEL_FINE,
};

let logLevel:string = 'debug';
if (!logLevel) {
  logLevel = 'info';
}

const getKeyValue = <T extends object, U extends keyof T>(obj: T) => (key: U) =>
  obj[key];
let _level = getKeyValue(LOG_LEVELS)(logLevel);
console.log(_level); // 1

Source: link

0

I am trying to convert the following React component to TypeScript:
import clsx from 'clsx'

type BGColors = {
	amber: string
	emerald: string
	fuchsia: string
	indigo: string
	lightBlue: string
	purple: string
	rose: string
}

const codeBackground: BGColors = {
	amber: 'bg-amber-500',
	emerald: 'bg-emerald-500',
	fuchsia: 'bg-fuchsia-400',
	indigo: 'bg-indigo-400',
	lightBlue: 'bg-light-blue-500',
	purple: 'bg-purple-400',
	rose: 'bg-rose-400',
}

const previewBackground: BGColors & { gray: string } = {
	amber: 'bg-gradient-to-r from-amber-50 to-amber-100',
	emerald: 'bg-gradient-to-r from-emerald-50 to-teal-100',
	fuchsia: 'bg-gradient-to-r from-fuchsia-50 to-fuchsia-100',
	gray: 'bg-gradient-to-r from-gray-50 to-gray-100',
	indigo: 'bg-gradient-to-r from-indigo-50 to-indigo-100',
	lightBlue: 'bg-gradient-to-r from-light-blue-50 to-light-blue-100',
	purple: 'bg-gradient-to-r from-purple-50 to-purple-100',
	rose: 'bg-gradient-to-r from-rose-50 to-rose-100',
}

type CodeSampleProps = {
	preview: string
	snippet: string
	previewClassName: string
	color: string
}

export const CodeSample = ({
	preview,
	snippet,
	previewClassName,
	color = 'gray',
}: CodeSampleProps) => {
	return (
		<div className="relative mb-8 overflow-hidden">
			<div
				className={clsx(
					'rounded-t-xl overflow-hidden',
					previewBackground[color],
					previewClassName,
					{
						'p-10': !previewClassName,
					}
				)}
				dangerouslySetInnerHTML={{ __html: preview }}
			/>
			<div
				className={clsx('overflow-hidden rounded-b-xl', codeBackground[color], {
					'bg-gray-800': !codeBackground[color],
				})}
			>
				<pre
					className={clsx(
						'scrollbar-none overflow-x-auto p-6 text-sm leading-snug language-html text-white',
						{
							'bg-black bg-opacity-75': codeBackground[color],
						}
					)}
				>
					<code className="language-html" dangerouslySetInnerHTML={{ __html: snippet }} />
				
</div> </div> ) }I did try:
color: keyof BGColors | keyof { gray: string }
And
color: keyof (BGColors & { gray: string })
The general pattern here is to use a type guard to confirm that key is keyof SomeObject. (wrote this on mobile, hopefully valid code)
const MyObject = {
    test: "hello"
}

function isMyObjectKey(key: string): key is keyof MyObject {
    return MyObject[key as unknown as keyof MyObject] !== undefined
}

const key: string = "test"

if (isMyObjectKey(key)) {
    MyObject[key]; // no error
}
Here's the code:
import clsx from 'clsx'

type BGColors = {
	amber: string
	emerald: string
	fuchsia: string
	gray: string
	indigo: string
	lightBlue: string
	purple: string
	rose: string
}

const codeBackground: Omit<BGColors, 'gray'> = {
	amber: 'bg-amber-500',
	emerald: 'bg-emerald-500',
	fuchsia: 'bg-fuchsia-400',
	// gray: 'bg-gray-400',
	indigo: 'bg-indigo-400',
	lightBlue: 'bg-light-blue-500',
	purple: 'bg-purple-400',
	rose: 'bg-rose-400',
}

const previewBackground: BGColors = {
	amber: 'bg-gradient-to-r from-amber-50 to-amber-100',
	emerald: 'bg-gradient-to-r from-emerald-50 to-teal-100',
	fuchsia: 'bg-gradient-to-r from-fuchsia-50 to-fuchsia-100',
	gray: 'bg-gradient-to-r from-gray-50 to-gray-100',
	indigo: 'bg-gradient-to-r from-indigo-50 to-indigo-100',
	lightBlue: 'bg-gradient-to-r from-light-blue-50 to-light-blue-100',
	purple: 'bg-gradient-to-r from-purple-50 to-purple-100',
	rose: 'bg-gradient-to-r from-rose-50 to-rose-100',
}

type CodeSampleProps = {
	preview: string
	snippet: string
	previewClassName: string
	color: keyof BGColors
}

export const CodeSample = ({
	preview,
	snippet,
	previewClassName,
	color = 'gray',
}: CodeSampleProps) => {
	return (
		<div className="relative mb-8 overflow-hidden">
			<div
				className={clsx(
					'rounded-t-xl overflow-hidden',
					previewBackground[color],
					previewClassName,
					{
						'p-10': !previewClassName,
					}
				)}
				dangerouslySetInnerHTML={{ __html: preview }}
			/>
			<div
				className={clsx(
					'overflow-hidden rounded-b-xl',
					color === 'gray' ? '' : codeBackground[color],
					{
						'bg-gray-800': color === 'gray' ? '' : !codeBackground[color],
					}
				)}
			>
				<pre
					className={clsx(
						'scrollbar-none overflow-x-auto p-6 text-sm leading-snug language-html text-white',
						{
							'bg-black bg-opacity-75': color === 'gray' ? '' : codeBackground[color],
						}
					)}
				>
					<code className="language-html" dangerouslySetInnerHTML={{ __html: snippet }} />
				
</div> </div> ) }

Source: link

Recent Questions on angular

    Programming Languages