Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling decorators with @ loses type safety with function as argument #58354

Closed
stavalfi opened this issue Apr 29, 2024 · 2 comments
Closed

Calling decorators with @ loses type safety with function as argument #58354

stavalfi opened this issue Apr 29, 2024 · 2 comments

Comments

@stavalfi
Copy link

πŸ”Ž Search Terms

decorator, function, type-safety, @, covariance, contravariance

πŸ•— Version & Regression Information

all versions

⏯ Playground Link

https://www.typescriptlang.org/play/?experimentalDecorators=true&emitDecoratorMetadata=true&ts=5.5.0-beta#code/PTAEHcAsFMDtQLbQC6QPYBMCMoBmBDASwBsBnUAWgD5QBjfYsvB4gI31oGsJDVRVooUviSh8AJwDmAVySxk5NLkQp02AFC5psWskJp4BRuy4AeALKrMWAGLxoAD2RwM5G9t37YAGlA2WJpx2oI7OsK6glqjWdlQAFAAO4mgJpABcoADezMYcQbAZ-rlcwQC+AJRZ6qCg4ijS4oYeegZxyBKSKBn4sACe3tU1oEkp0OLIvQDS0L0ZpMjihLCSA0OgGNCktIsJyGjiGQAqvQnQGAAKyafjvQAim9uEu-sWVtixg5WZgzUgoIQIBLEaByZA5Nh5UDENCSQi0AB0iJ+tXqjXWDx2e3Eg1KAG51KV1Oo-gBhFjo2j7fBYnh8AAClBosDQdDQgJI1K8IXEyXEoDScSJtGI+FI5HMvRJIrFOG+vzAAEkQg5TroxKz2SKWvYeftQKxoPRpKRBEUISV4Bg0JtQMywaEXJE3rZYIM6UZzZw4tkPYE7BlEld0llQA4MrBZAa+RU0hGEFHQABeGjZOrIBrwAAMoFKOcqf3A+04pAAhBBIL0APyVwbzTm0FTRbBS0WkQNoYPZGO2yNjKprNMZ0BYHEEomk8kbSnial6jCEOq6Yi9RkahIc7Xc3n88pEianPwBPLBROgOKBhIdjLZMM9+N9ipJpm98SVdT7wRRNQupNni9XkNH2TO8ozfdQpxFOpWVgeZwT9AozXg8DDUgwRKRgsEkCbF00i-GJXWJMASTZdctS5MZtwoChQAAQQAZWVVVnAwEsS00I8zDw94fEQ49YHiTJfT4vM4gjRhvAAIiwCTvEyAA3BhpGgNIsO-OwKkItYtO0moAD19IMwygA

πŸ’» Code

// when method1 fails -> calls fallback with the same arguments of method1
function fallback<Method1Fn extends Function, FallbackFn extends Method1Fn>(props: { fallbackFn: FallbackFn }) {
  return function(target: any,
    propertyKey: string,
    descriptor: TypedPropertyDescriptor<Method1Fn>
  ) {
    // implement fallback logic...
    return descriptor
  };
}

// Call decorator with @ -> no compilation error :(

class MyClass1 {
  // I expect a compilation error because FallbackFn does not extend Method1Fn
  @fallback({ fallbackFn: (props: { x: number }):number => { return 0 } }) // works! why??
  static method1Class(pros: { }): number {
    return 1
  }
}

// Call decorator directly -> compilation error :)

type FallbackFn = ((prpos: { x: number }) => number) 
type Method1Fn = ((prpos: { }) => number) 

declare const fallbackFn:FallbackFn
declare const method1Fn:Method1Fn

// Compilation error -- AS expected!!
fallback<Method1Fn,FallbackFn>({fallbackFn })(null,"1",{value:method1Fn})
//                 ^^^^^^^^^^

πŸ™ Actual behavior

The decorator have constriant: FallbackFn extends Method1Fn but it is not honored when calling a decorator with @. But it is honored when calling the decorator as a function directly.

πŸ™‚ Expected behavior

Expect the same error when calling the decorator with @ as we see when calling the decorator as a function directly.

Additional information about the issue

No response

@stavalfi stavalfi changed the title Decorators genereics lose type safely with function as argument Calling decorators with @ loses type safety with function as argument Apr 29, 2024
@jcalz
Copy link
Contributor

jcalz commented Apr 30, 2024

This isn't a TypeScript bug and doesn't have anything to do with decorators, really. It's method parameter bivariance, which is working as intended. With --strictFunctionTypes enabled, Method1Fn and typeof MyClass1["method1Class"] are checked differently even though their IntelliSense looks the same. If you change Method1Fn to

type Method1Fn = typeof MyClass1["method1Class"];

then the error goes away in both instances, see Playground Link.

@stavalfi
Copy link
Author

stavalfi commented May 1, 2024

@stavalfi stavalfi closed this as completed May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants