Is it possible to define an object literal type in typescript that permits unspecified properties?

I am looking to make sure that an object argument has all the necessary properties, while also allowing for additional properties. For instance:

function verifyObject(input: { key: string }) : number {
    return input.key;
}

verifyObject({ key: 'value', extra: 'data' });

However, when doing this, it gives the error message:

Object literal can only define known properties, and 'extra' is not present in type '{ key: string; }'.

Answer №1

Absolutely! Give this a shot:

interface IFoo {
    foo: string;
    [key: number]: any;
}

function bar(baz: IFoo) : string {
    return baz.foo;
}

bar({ foo: "hello", other: "world" });

Answer №2

Although I usually don't enjoy answering my own questions, the responses from others sparked some inspiration. Here is a solution that seems to work:

function foo<T extends { baz: number }>(bar: T): void {
    console.log(bar.baz);
}

foo({baz: 1, other: 2});

Answer №3

If you're dealing with known fields from a generic type, the way to allow wildcards is by using T & {[key: string]: unknown}. Any fields that are known must comply with the type's constraints, while other fields are allowed (and considered of type unknown).

Here's an example:

type WithWildcards<T> = T & { [key: string]: unknown };

function test(foo: WithWildcards<{baz: number}>) {}

test({ baz: 1 }); // works
test({ baz: 1, other: 4 }); // works
test({ baz: '', other: 4 }); // fails since 'baz' isn't a number

Then, if you have a generic type T, you can allow wildcard fields with WithWildCards<T>.

Note that extra properties aren't flagged as errors if the object comes from anything other than an object literal. TypeScript just informs you that adding those properties in the literal is unnecessary.

Check out some other scenarios where extra properties are and aren't permitted

interface Foos{
  a?: string
  b?: string
}
type WithWildcards<T> = T & { [key: string]: unknown };

declare function acceptFoos(foo: Foos): void;
declare function acceptWild(foo: WithWildcards<Foos>):void

acceptFoos(  {a:'', other: ''}) // ERROR as the property is extraneous
const data = {a:'', other: ''}
acceptFoos(  data) // allowed as it's compatible; TypeScript doesn't require removing properties
const notCompat = {other: ''}
acceptFoos(notCompat) //ERROR: Type '{ other: string; }' has no properties in common with type 'Foos'
acceptFoos({a:'', ...notCompat}) // this is also allowed 
acceptWild(notCompat) // allowed

Answer №4

Using the Record type in TypeScript allows you to accept unknown properties for the entire object.

function processInput(data: Record<string|number, unknown>): Record<string|number, unknown> {
  return { newProp: 'newValue' }
}

Answer №5

To achieve this task, it is recommended to create a type definition specifically for the function parameter. The following code snippet demonstrates how to do this using inline type definition:

function calculateValue(data: { value: number }) : number {
    return data.value;
}

const myData = { value: 10, otherValue: 20 };

calculateValue(myData);

Answer №6

When dealing with a variable of the unknown type, you can utilize the concept of narrowing to determine and manipulate the specific type you expect from the value you are handling.

const messages: string [] = Object.values(obj).map(val => typeof obj === 'object' ? obj!['message'] : obj)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ReactJS Provider not passing props to Consumer resulting in undefined value upon access

Hey there! I've been facing an issue with passing context from a Provider to a consumer in my application. Everything was working fine until suddenly it stopped. Let me walk you through a sample of my code. First off, I have a file named AppContext.t ...

Tips for Maintaining User Sessions in Ionic 4 Application

I am facing an issue with keeping users logged in to the app in Ionic 4. I have tried storing credentials like email and cross-checking the user using an API, then redirecting to the menu page. However, I am experiencing a brief moment on the login page be ...

React typed (script) properties are not validated

Embarking on a brand new app development journey with React, I decided to experiment with TypeScript for the very first time. I have a React component set up like this: import React, { SFC } from 'react'; type Props = { username: string }; ...

In Ionic 3, the term "Twilio" is not recognized

Attempting to integrate Twilio into my Ionic 3 application has been a bit of a challenge. While it works fine when tested on a browser, running it on an actual device led to a frustrating error message: TypeError: undefined is not a function {stack: (...), ...

Type of event target MouseEvent

I am currently working on a custom hook const hasIgnoredClass = (element: Element, ignoredClass: string) => (element.correspondingElement ? element.correspondingElement : element ).classList.contains(ignoredClass); const isInIgnoredElement = ( ...

`Incredible sequence of events unfolding`

In order to add an additional action after the deletion process is complete, I must make modifications to an epic. The current epic code is as follows: const deleteComponentEpic: Epic< AppActions, AppActions, AppStore, ComponentDetailsEpicsDepen ...

Retrieve the value of a variable to access an object property dynamically in React Native using TypeScript

As I attempted to create dynamic styles for this component, my goal was to determine the styles based on a string passed in as a property. Here is the code snippet: export type MyComponentProps = { styleName: string; } const MyComponent = (props: MyComp ...

Trouble arises when extending an MUI component due to a TypeScript error indicating a missing 'css' property

We have enhanced the SnackbarContent component by creating our own custom one called MySnackbarContent: export interface MySnackbarContentProps extends Omit<SnackbarContentProps, 'variant'> { variant?: MyCustomVariant; type?: MyCustomTy ...

Ways to assign a random color to every card displayed in a screenshot in Angular 6?

[![enter image description here][1]][1] This is the HTML component code: <div class="row"> <div class="col-lg-3 col-md-3 col-sm-6 col-12"> <a href="javascript:void(0)" (click)="openModal()"> <div class="card card-box HYT ...

What is the best way to add elements to a custom-defined array?

I am currently utilizing Angular 5 with typescript version 2.7.1. Within typescript, I have created a custom type: arr: {id: string; name: string; }[]; I am attempting to add an element to the array and have experimented with the following methods: thi ...

Evaluating whether an imported function, which serves as a dependency of an adapter, is being invoked with accurate parameters within the adapter using the Jest testing framework

Here is how my test looks import { SlugGeneratorAdapter } from './slug-generator-adapter' import slugify from 'slugify' describe('SlugGenerator Adapter', () => { test('Should call the slug generator with the correct ...

A guide on how to navigate to a customizable element in React Native

After creating a glossary, I needed a way to access the content of a specific letter by clicking on that letter from a list displayed at the top of my page. However, I encountered an issue - while I managed to implement scrolling functionality, I couldn&ap ...

Is there a way to determine the quantity of lines within a div using a Vue3 watcher?

Is it feasible to determine the number of text lines in a div without line breaks? I am looking to dynamically display or hide my CTA link based on whether the text is less than or equal to the -webkit-line-clamp value: SCRIPT: const isExpanded = ref(true ...

Incorporate MUX Player (Video) into Angular versions 14 or 15

Mux offers a video API service with its own player: MUX Player I am interested in integrating this npm package specifically into a component in Angular 14/15. The JavaScript should only be loaded when this particular component is rendered. Integration Th ...

I am facing an issue with my interface - the variable designed to store boolean values

Something unusual happened with Typescript - I assigned a string value to a boolean variable, but no error was generated. I purposely triggered an error in order to observe how Typescript would react, only to find that it did not produce the expected erro ...

Guide to crafting a personalized parameter decorator for extracting the user from a request

Within my express.js application, I have set up an endpoint where I extract the user from the request as shown below: @Put('/:_id') async update (@Request() req: express.Request) { // @ts-ignore const user = req.user; .... } I am intereste ...

Avoid insecurely assigning an any value in TypeScript

Take a look at this code snippet: const defaultState = () => { return { profile: { id: '', displayName: '', givenName: '', }, photo: '', } } const state = reactive(defaultState() ...

Develop an enhancement for the Date object in Angular 2 using Typescript

Using the built-in Date type, I can easily call date.getDate(), date.getMonth()...etc. However, I am looking for a way to create a custom function like date.myCustomFunctionToGetMonthInString(date) that would return the month in a string format such as &a ...

Implementing Service Communication

I created an Angular Application using the Visual Studio Template. The structure of the application is as follows: /Clientapp ./app/app.module.shared.ts ./app/app.module.client.ts ./app/app.module.server.ts ./components/* ./services/person-data.service. ...

Error: NullInjector - The injector encountered an error when trying to inject the Component into the MatDialogRef in the AppModule

When utilizing a component via routing as well as injecting it as the "target" of a modal dialog, I encountered an issue: export class Component1 implements OnInit { constructor(private service: <someService>, public dialogRef: MatDialogRef<Compo ...