Comments (13)
@IgorKha ah, i know what's going on. Will fix, thanks for catching
from openapi-ts.
@julianklumpers Are you creating those before/after yourself? If so, how and why?
I thought about passing it as the last argument but think I had an issue with it not being typed correctly when using optional values. I can revisit, want to open an issue for it?
created a issue: 888
from openapi-ts.
Hey @IgorKha can you check whether you really have the latest Axios client installed?
from openapi-ts.
This will be fixed in the next release, thanks for catching!
from openapi-ts.
The problem partly still remains. This problem did not exist before and intellisense(for error) does not work.
"@hey-api/openapi-ts": "^0.52.3",
"@hey-api/client-axios": "^0.2.1",
"axios": "^1.7.3",
// Example
import { createClient } from '@hey-api/client-axios'
const client = createClient({
baseURL: import.meta.env.VITE_BASE_URL
})
const login = async (username: string, password: string, remember: boolean) => {
try {
const { data, error, request } = await AuthService.loginV1AuthLoginPost({
client: client,
body: {
grant_type: 'password',
username,
password
},
query: {
remember
}
})
if (error) {
errorStatusCode.value = error.status_code
throw new Error(error)
}
} catch (err) {
console.error(err.message)
}
}
src/stores/userStore.ts:54:39 - error TS2339: Property 'status_code' does not exist on type 'LoginV1AuthLoginPostError'.
Property 'status_code' does not exist on type 'HTTPValidationError'.
54 errorStatusCode.value = error.status_code
~~~~~~~~~~~
Thank you so much )
from openapi-ts.
@IgorKha Would you be able to do either:
- create a StackBlitz example
- locally, go to the error type for this endpoint. You will see it's a union type of all possible errors (
|
). Try changing it to intersection (&
) and see if the error disappears for this statement you showed me?
I'd prefer a StackBlitz example but either one would help. Thanks!
from openapi-ts.
@mrlubos yes, if I change to (types.gen.ts)export type LoginV1AuthLoginPostError = HttpResponse & HTTPValidationError
, this error disappears :)
I'll try to create an example on StackBlitz a little later.
from openapi-ts.
@IgorKha are you able to drop here schemas for HTTPValidationError
and HttpResponse
? Will be faster than creating an example
from openapi-ts.
types.gen.ts
// types.gen.ts
// This file is auto-generated by @hey-api/openapi-ts
export type Body_login_v1_auth_login_post = {
grant_type?: string | null
username: string
password: string
scope?: string
client_id?: string | null
client_secret?: string | null
}
export type HTTPValidationError = {
detail?: Array<ValidationError>
}
/**
* Data model for HTTP response.
*/
export type HttpResponse = {
status_code: number
message: string
}
/**
* Data model for tokens.
*/
export type TokenResponse = {
access_token: string
}
export type ValidationError = {
loc: Array<string | number>
msg: string
type: string
}
export type LoginV1AuthLoginPostData = {
body: Body_login_v1_auth_login_post
query?: {
remember?: boolean
}
}
export type LoginV1AuthLoginPostResponse = TokenResponse
export type LoginV1AuthLoginPostError = HttpResponse & HTTPValidationError
export type RefreshTokenV1AuthRefreshTokenPostResponse = TokenResponse
export type RefreshTokenV1AuthRefreshTokenPostError = HttpResponse
export type TestJwtV1AuthTestJwtGetResponse = {
[key: string]: string
}
export type TestJwtV1AuthTestJwtGetError = HttpResponse
export type TestApiKeyV1AuthTestApiKeyGetResponse = {
[key: string]: string
}
export type TestApiKeyV1AuthTestApiKeyGetError = HttpResponse
export type TestBothAuthV1AuthBothAuthRouteGetResponse = {
[key: string]: string
}
export type TestBothAuthV1AuthBothAuthRouteGetError = HttpResponse
export type MsgV1ExpMsgPostData = {
query: {
msg: string
}
}
export type MsgV1ExpMsgPostResponse = string
export type MsgV1ExpMsgPostError = HTTPValidationError
export type PrivateV1ExpPrivatePostData = {
query: {
msg: string
}
}
export type PrivateV1ExpPrivatePostResponse = string
export type PrivateV1ExpPrivatePostError = HTTPValidationError
export type $OpenApiTs = {
'/v1/auth/login': {
post: {
req: LoginV1AuthLoginPostData
res: {
/**
* Successful Response
*/
'200': TokenResponse
/**
* Unauthorized
*/
'401': HttpResponse
/**
* Forbidden
*/
'403': HttpResponse
/**
* Validation Error
*/
'422': HTTPValidationError
}
}
}
'/v1/auth/refresh-token': {
post: {
res: {
/**
* Successful Response
*/
'200': TokenResponse
/**
* Unauthorized
*/
'401': HttpResponse
/**
* Forbidden
*/
'403': HttpResponse
}
}
}
'/v1/auth/test-jwt': {
get: {
res: {
/**
* Successful Response
*/
'200': {
[key: string]: string
}
/**
* Unauthorized
*/
'401': HttpResponse
/**
* Forbidden
*/
'403': HttpResponse
}
}
}
'/v1/auth/test-api-key': {
get: {
res: {
/**
* Successful Response
*/
'200': {
[key: string]: string
}
/**
* Unauthorized
*/
'401': HttpResponse
/**
* Forbidden
*/
'403': HttpResponse
}
}
}
'/v1/auth/both-auth-route': {
get: {
res: {
/**
* Successful Response
*/
'200': {
[key: string]: string
}
/**
* Unauthorized
*/
'401': HttpResponse
/**
* Forbidden
*/
'403': HttpResponse
}
}
}
'/v1/exp/msg': {
post: {
req: MsgV1ExpMsgPostData
res: {
/**
* Successful Response
*/
'200': string
/**
* Validation Error
*/
'422': HTTPValidationError
}
}
}
'/v1/exp/private': {
post: {
req: PrivateV1ExpPrivatePostData
res: {
/**
* Successful Response
*/
'200': string
/**
* Validation Error
*/
'422': HTTPValidationError
}
}
}
}
schemas.gen.ts
// schemas.gen.ts
// This file is auto-generated by @hey-api/openapi-ts
export const $Body_login_v1_auth_login_post = {
properties: {
grant_type: {
anyOf: [
{
type: 'string',
pattern: 'password'
},
{
type: 'null'
}
],
title: 'Grant Type'
},
username: {
type: 'string',
title: 'Username'
},
password: {
type: 'string',
title: 'Password'
},
scope: {
type: 'string',
title: 'Scope',
default: ''
},
client_id: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Client Id'
},
client_secret: {
anyOf: [
{
type: 'string'
},
{
type: 'null'
}
],
title: 'Client Secret'
}
},
type: 'object',
required: ['username', 'password'],
title: 'Body_login_v1_auth_login_post'
} as const
export const $HTTPValidationError = {
properties: {
detail: {
items: {
$ref: '#/components/schemas/ValidationError'
},
type: 'array',
title: 'Detail'
}
},
type: 'object',
title: 'HTTPValidationError'
} as const
export const $HttpResponse = {
properties: {
status_code: {
type: 'integer',
title: 'Status Code'
},
message: {
type: 'string',
title: 'Message'
}
},
type: 'object',
required: ['status_code', 'message'],
title: 'HttpResponse',
description: 'Data model for HTTP response.'
} as const
export const $TokenResponse = {
properties: {
access_token: {
type: 'string',
title: 'Access Token'
}
},
type: 'object',
required: ['access_token'],
title: 'TokenResponse',
description: 'Data model for tokens.'
} as const
export const $ValidationError = {
properties: {
loc: {
items: {
anyOf: [
{
type: 'string'
},
{
type: 'integer'
}
]
},
type: 'array',
title: 'Location'
},
msg: {
type: 'string',
title: 'Message'
},
type: {
type: 'string',
title: 'Error Type'
}
},
type: 'object',
required: ['loc', 'msg', 'type'],
title: 'ValidationError'
} as const
OpenAPI:
{
"openapi": "3.1.0",
"servers": [
{
"url": "/api"
}
],
"paths": {
"/v1/auth/login": {
"post": {
"tags": [
"auth"
],
"summary": "Login",
"description": "Authenticates",
"operationId": "login_v1_auth_login_post",
"parameters": [
{
"name": "remember",
"in": "query",
"required": false,
"schema": {
"type": "boolean",
"default": false,
"title": "Remember"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"$ref": "#/components/schemas/Body_login_v1_auth_login_post"
}
}
}
},
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenResponse"
}
}
}
},
"401": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
},
"description": "Unauthorized"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
},
"description": "Forbidden"
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/v1/auth/refresh-token": {
"post": {
"tags": [
"auth"
],
"summary": "Refresh Token",
"description": "Refresh",
"operationId": "refresh_token_v1_auth_refresh_token_post",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TokenResponse"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
}
}
}
},
"/v1/auth/test-jwt": {
"get": {
"tags": [
"auth"
],
"summary": "Test Jwt",
"description": "Protected route that requires authentication.\n\nArgs:\n----\n current_user (User): The authenticated user.\n\nReturns:\n-------\n dict[str, str]: A dictionary with a message indicating access granted.",
"operationId": "test_jwt_v1_auth_test_jwt_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"title": "Response Test Jwt V1 Auth Test Jwt Get"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
}
},
"security": [
{
"OAuth2PasswordBearer": []
}
]
}
},
"/v1/auth/test-api-key": {
"get": {
"tags": [
"auth"
],
"summary": "Test Api Key",
"description": "APIKey Route.\n\nArgs:\n----\n api_key (str, optional): The API key.\n\nReturns:\n-------\n dict[str, str]: A dictionary with a message indicating access granted.",
"operationId": "test_api_key_v1_auth_test_api_key_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"title": "Response Test Api Key V1 Auth Test Api Key Get"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
}
},
"security": [
{
"APIKeyHeader": []
}
]
}
},
"/v1/auth/both-auth-route": {
"get": {
"tags": [
"auth"
],
"summary": "Test Both Auth",
"description": "Test route to check auth for api key and oauth2",
"operationId": "test_both_auth_v1_auth_both_auth_route_get",
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"title": "Response Test Both Auth V1 Auth Both Auth Route Get"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HttpResponse"
}
}
}
}
},
"security": [
{
"APIKeyHeader": []
},
{
"OAuth2PasswordBearer": []
}
]
}
},
"/v1/exp/msg": {
"post": {
"tags": [
"exp"
],
"summary": "Msg",
"operationId": "msg_v1_exp_msg_post",
"parameters": [
{
"name": "msg",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Msg"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"type": "string",
"title": "Response Msg V1 Exp Msg Post"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
},
"/v1/exp/private": {
"post": {
"tags": [
"exp"
],
"summary": "Private",
"operationId": "private_v1_exp_private_post",
"parameters": [
{
"name": "msg",
"in": "query",
"required": true,
"schema": {
"type": "string",
"title": "Msg"
}
}
],
"responses": {
"200": {
"description": "Successful Response",
"content": {
"application/json": {
"schema": {
"type": "string",
"title": "Response Private V1 Exp Private Post"
}
}
}
},
"422": {
"description": "Validation Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Body_login_v1_auth_login_post": {
"properties": {
"grant_type": {
"anyOf": [
{
"type": "string",
"pattern": "password"
},
{
"type": "null"
}
],
"title": "Grant Type"
},
"username": {
"type": "string",
"title": "Username"
},
"password": {
"type": "string",
"title": "Password"
},
"scope": {
"type": "string",
"title": "Scope",
"default": ""
},
"client_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Client Id"
},
"client_secret": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Client Secret"
}
},
"type": "object",
"required": [
"username",
"password"
],
"title": "Body_login_v1_auth_login_post"
},
"HTTPValidationError": {
"properties": {
"detail": {
"items": {
"$ref": "#/components/schemas/ValidationError"
},
"type": "array",
"title": "Detail"
}
},
"type": "object",
"title": "HTTPValidationError"
},
"HttpResponse": {
"properties": {
"status_code": {
"type": "integer",
"title": "Status Code"
},
"message": {
"type": "string",
"title": "Message"
}
},
"type": "object",
"required": [
"status_code",
"message"
],
"title": "HttpResponse",
"description": "Data model for HTTP response."
},
"TokenResponse": {
"properties": {
"access_token": {
"type": "string",
"title": "Access Token"
}
},
"type": "object",
"required": [
"access_token"
],
"title": "TokenResponse",
"description": "Data model for tokens."
},
"ValidationError": {
"properties": {
"loc": {
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"type": "array",
"title": "Location"
},
"msg": {
"type": "string",
"title": "Message"
},
"type": {
"type": "string",
"title": "Error Type"
}
},
"type": "object",
"required": [
"loc",
"msg",
"type"
],
"title": "ValidationError"
}
},
"securitySchemes": {
"OAuth2PasswordBearer": {
"type": "oauth2",
"flows": {
"password": {
"scopes": {},
"tokenUrl": "login"
}
}
},
"APIKeyHeader": {
"type": "apiKey",
"in": "header",
"name": "X-API-Key"
}
}
}
}
from openapi-ts.
Yeah I don't think this is a bug anymore @IgorKha, the previous implementation was incorrect. When you assign error.status_code
to your value, this field can be undefined because it does not exist on one of the possible returned error types. The previous code worked for you because you got lucky and your errors are objects. But imagine if one of the possible errors was a string, then accessing status_code on it would throw a runtime error.
You will want to explicitly check if that field exists to narrow the type. There's a related issue #495 where people asked for a different approach by status code, but the problem is the same.
from openapi-ts.
I see, thanks for your time. i will read the neighboring thread more closely to understand :)
from openapi-ts.
With the latest version where this was problem was fixed, the typescript implementation has changed for the fetch-client
. I now have to explicitly specify a boolean type as a generic.
I see that the type has changed, if this is intentional, I would suggest placing the ThrowOnError
as the last argument. As we now have to specify a boolean type in all our services now.
type MethodFn = <ThrowOnError extends boolean, Data = unknown, TError = unknown>(options: Omit<RequestOptionsBase<ThrowOnError>, 'method'>) => RequestResult<ThrowOnError, Data, TError>;
Before
export const UpdateProfile = (options: Options<{ path: { userId: string } }>) => {
return (options?.client ?? client).patch<ProfileUser, ApiError>({
...options,
url: '/api/nl/users/{userId}',
});
};
After
export const UpdateProfile = (options: Options<{ path: { userId: string } }>) => {
return (options?.client ?? client).patch<boolean, ProfileUser, ApiError>({ // all good now
...options,
url: '/api/nl/users/{userId}',
});
};
from openapi-ts.
@julianklumpers Are you creating those before/after yourself? If so, how and why?
I thought about passing it as the last argument but think I had an issue with it not being typed correctly when using optional values. I can revisit, want to open an issue for it?
from openapi-ts.
Related Issues (20)
- Improper handling of array query types HOT 6
- Having trouble setting up client with next js and fetch api HOT 4
- Properties are declared `?` when they're not in the openapi spec HOT 5
- Type of error object changed HOT 2
- Cannot specify responseTransformer when request options include headers HOT 1
- Generating code based on multiple OpenAPI schemas HOT 3
- Automatic addition of the suffix `Schema` to the object names in `schemas.gen.ts` causes conflicts with `types.gen.ts` HOT 3
- Intergrate with `msw` mock service HOT 1
- Improve changelog
- Test bundle-require
- Angular client
- Posibility to add no client HOT 14
- Big int for Format int64 HOT 1
- Build Error in @hey-api/client-fetch v0.3.2: Unnamed ‘Client’ and ‘RequestOptionsBase’ Issues HOT 9
- Dynamic require of "child_process" is not supported HOT 3
- openapi-ts version 0.53.3 breaks esm build HOT 1
- Generating names with search parameters from URL HOT 5
- `@tanstack/react-query` is not compatible with `asClass` services HOT 5
- @hey-api/[email protected] doesn't export type RequestResult HOT 2
- @hey-api/client-fetch is incompatible with `asClass: true`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openapi-ts.