Prevent a TypeScript generic object from containing a specific property

I've encountered a situation where I need to create a generic function that accepts an object as a parameter, but with the condition that the object cannot have properties in the format __property__. Currently, my approach is:

type RemoveProps = {
    [K in keyof T as K extends `__${infer _K}__` ? never : K]: T[K];
}

function doSomething<T extends {}>(arg: RemoveProps<T>): 
{
    // ...
}

Although this works fine, it doesn't prevent scenarios like this:

doSomething<{ __not_allowed__: any }>(arg);

Is there a way to make TypeScript throw an error if the generic type contains these prohibited properties?

Answer №1

The most straightforward approach would be to associate undesirable property value types with the 'never' type rather than excluding them completely. Excluding a property does not hinder assignability: { __x__: 0, y: 1 } is an extension of { y: 1}, but it does not extend { __x__: never, y: 1 }:

type ProhibitProps<T> = {
  [K in keyof T]: K extends `__${string}__` ? never : T[K]
}

function doSomething<T extends ProhibitProps<T>>(
  arg: T
) { }

doSomething<{ __not_allowed__: any }>({ ok: 123 }); // error!
// -------> ~~~~~~~~~~~~~~~~~~~~~~~~
// Type '{ __not_allowed__: any; }' does not satisfy the 
//   constraint 'ProhibitProps<{ __not_allowed__: any; }>'.
// Types of property '__not_allowed__' are incompatible.
// Type 'any' is not assignable to type 'never'.

doSomething<{ ok: 123 }>({ ok: 123 }); // okay

Seems like a reliable solution!

Playground link to code

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

Difficulty in detecting variable modifications during testing - Angular2+

After successful login, I expect a certain variable to be updated with the appropriate value. However, during testing, all I see is 'undefined' returned. This variable does change when interacting with the app, showing an error message like &apo ...

Ways to effectively implement a function type specified in an interface

Consider the following interface: interface MyProps { onEvent: (name: string, data: any) => void; } Is there a way to utilize the function type in order to avoid unused parameter errors during compilation? eventHandler = (name: string, data: any) = ...

A guide on setting a default constructor as a parameter in TypeScript

Through collaboration with a fellow coder on StackOverflow, I have mastered the art of specifying a constructor as an argument to a class: type GenericConstructor<T> = { new(): T; } class MyClass<T> { subclass: T; constructor( SubClas ...

InvalidTypeException: The properties accessed are undefined

Working with Angular 12 and encountering an error when trying to invoke a method within another method. Here is a simplified representation of my situation (in TypeScript, specifically for Angular: export class SomeClass { testvariable on ...

Transfer Typescript Project to Visual Studio Code

When I first started my project, I used the Typescript HTML Application Template project template. It worked well and set up a project for me. However, now I want to transition to using VSCode. The issue I'm facing is figuring out which switches and c ...

The type 'string' cannot be assigned to type 'ImageSourcePropType'

Context Attempting to utilize a SVG component in React Native with the xlinkHref property within an Image tag. The SVG file was converted into a React Native Component (TSX) using the tool provided at . While simple SVG icons have been successfully used be ...

Executing a Typescript function in an MVC5 cshtml file, optimized with webpack bundling

Brand new to webpack, and I'm facing obstacles in merging MVC components with webpack AND typescript. Take a look at my code combinations below: webpack.config.js: var wbConfigEntries = { "jqkendoMain": [ paths.appjs + "main.ts" ] }; ...

Troubleshooting why the Typescript Omit property is not functioning correctly when used with the 'as' keyword

When both properties are needed during registration, but only one is necessary after, the system utilizes Firebase built-in functions for authentication and registration purposes. All other information will be stored in the Firebase user collection. The i ...

Tips for bypassing switch statements in typescript while handling discriminators?

Is there a way to refactor the code below to eliminate the switch case while maintaining type safety? I've encountered this issue several times and am looking for a pattern that utilizes a map or another approach instead of a switch case. function tra ...

Key constraints in generics: a key must belong to a distinct object type

Is there a way to enhance the safety of this function even further? Consider this object/shape: export const initialState: State = { foods: { filter: '', someForm: { name: '', age: 2, ...

Is there a way to define type information for a global variable when utilizing dynamic import within a function?

Here is a simplified version of my server code: server.ts import google from "googleapis"; const androidPublisher = google.androidpublisher("v3"); app.use('something', function(req, res, n){ ... }) ...(only one of the dozens of other meth ...

Accessing a targeted XML file within a document using Office.js in a Word Add-In

I am struggling to load the file named item1.xml from the ..\customXml folder of my document into my Word Add-In. So far, I have attempted the following: var url = Office.context.document.url + '\\customXml\\item1.xml\& ...

When working with Angular/Typescript, the error message "compilation of 'export const' is not possible

Embarking on creating my very own Angular library, I took the first step by adding a service without any issues. The challenge arose when I decided to move a constant to a file named tokens.ts for the service to reference. Following this change, the build ...

Encountered a Building Error: "The type .... is included in the declarations of two modules: AppModule and Ionic."

As I strive to generate my APK for Android, I executed the following command: ionic cordova run android --prod --release Version of Ionic being used: Ionic V3 My app currently does not employ lazy loading (I confess I am not even sure how to go about th ...

Enhance Your MUI React Component with Custom Styles and ThemeProvider Integration

Currently, I am delving into the world of MUI components within a React environment. Specifically, I am utilizing MUI 5 and React 17. These MUI components are sourced from a third-party library, resulting in limited direct access. My current goal is to rev ...

TypeScript and Node.js: The type of 'this' is implicitly set to 'any'

Help Needed with TypeScript issue: An issue is arising in my TypeScript code related to a mongoose schema's post function. It is used to generate a profile for a user upon signing up, using the User model. Even though the code functions properly, th ...

What could be causing the countdown timer to speed up unexpectedly?

Currently, I am developing a quiz application. At the moment, I need to implement the following features: Countdown timer Questions Question Choices The countdown timer for each question functions properly as long as the answer button is not clicked or ...

The announcement will not be made as a result of the utilization of a private name

I've been working on transitioning a project to TypeScript, and while most of the setup is done, I'm struggling with the final steps. My goal is to use this TypeScript project in a regular JavaScript project, so I understand that I need to genera ...

I'm having trouble resolving this issue with an Unexpected Application Error! It seems that I cannot set the property value of #<TextFieldBase2> since it only has a

Currently, I'm utilizing TypeScript, React Hook Form, Yup validation, and Fluent UI. Every time I attempt to submit a form, I encounter the error 'Unexpected Application Error! Cannot set property value of # which has only a getter'. https:/ ...

The pipe property cannot be accessed for the specified type "OperatorFunction<unknown, [unknown, boolean, any]>"

I have set up a data subscription that I want to utilize through piping, but for some reason it's not working as expected. The error message I'm receiving is: The property pipe is not available for type "OperatorFunction<unknown, [unknown, b ...