gpt4 book ai didi

json - TypeScript:将原始数据解析为接口(interface)

转载 作者:行者123 更新时间:2023-12-02 00:48:27 26 4
gpt4 key购买 nike

在 Typescript(特别是 React with hooks)中,我试图从 OAuth 回调中解析一些 URL 哈希数据,并在我的组件中使用它。

我可以通过调用 window.location.hash 来解析我的数据

const hash = window.location.hash.substr(1);
const oauthData = hash.split('&')
.map(v => v.split('='))
.reduce((pre, [key, value]) => (
key == 'scope' ? {...pre, [key]: value.split('+')} : {...pre, [key]: value}
), {});
{
"access_token": "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyMkJCWVkiLCJzdWIiOiI1TkZCTFgiLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4iLCJzY29wZXMiOiJyc29jIHJhY3QgcnNldCBybG9jIHJ3ZWkgcmhyIHJudXQgcnBybyByc2xlIiwiZXhwIjoxNTc4NTQ3NzkxLCJpYXQiOjE1NzgyMDQzOTF9.qLl0L5DthFu3NxeLodotPsPljYMWgw1AvKj2_i6zilU",
"user_id": "5NFBLX",
"scope": [
"heartrate",
"nutrition",
"location",
"sleep",
"activity",
"weight",
"social",
"profile",
"settings"
],
"token_type": "Bearer",
"expires_in": "343400"
}

太棒了!现在我想将所有这些信息传递到我的组件中,这就是事情变得有点困惑的地方,我无法找到将这些数据放入我的组件的方法,因为我破坏了类型安全。

我的组件是这样构建的

export interface IOAuthProps {
accessToken: string
userID: string
scope: string[]
expiresIn: number
}

const OAuthFun: React.FC<IOAuthProps> = (props) => {

const [ac] = useState(props.accessToken)
return (
<div>
access token = {ac}
</div>
)
}

export default OAuthFun;

我已经尝试了这些看似相同的事物的排列(为简洁起见,我将省略其他属性):

非工作示例:甚至无法索引 oauthData,因为它属于 {}

<OAuthFun accessToken={oauthData['access_token'] as string}/>

因为我什至无法将原始 json 对象作为字典进行索引,所以我想我需要在正在构建的对象上创建一些类型安全:

  const oauthData = hash.split('&')
.map(v => v.split('='))
.reduce((pre, [key, value]) => (
key == 'scope' ? {...pre, [key]: value.split('+')} : {...pre, [key]: value}
), {access_token: String, user_id: String, scope: [], expires_in: Number});

但是,这会破坏我的 reduce 调用中的表达式:没有重载匹配此调用。 这让我相信我需要一些更简洁的方法来解析原始数据,但我我真的不确定该怎么做。

我想我可以将其直接从原始数据转换为界面,但原始数据的命名约定使用 underscore_casing 而不是 camelCasing。此外,如果我更改大小写而不是学习如何规范化数据,它只是回避问题而不解决问题。

将原始数据直接放入界面的正确方法是什么?

最佳答案

根据评论,我能够拼凑出这个解决方案。

import React from 'react';

export interface IOAuthProps {
accessToken: string
userID: string
scope: string[]
expiresIn: number
}

export function ParseOAuthProperties(rawHashProperties: string): IOAuthProps {
const rawData = rawHashProperties.substr(1)
.split('&')
.map(v => v.split('='))
.reduce((pre, [key, value]) => (
{...pre, [key]: value}
), {access_token: "", user_id: "", scope: "", expires_in: ""});
const normalizedData: IOAuthProps = {
accessToken: rawData.access_token,
userID: rawData.user_id,
scope: rawData.scope.split('+'),
expiresIn: Number(rawData.expires_in),
}
return normalizedData;
}

const OAuthFun: React.FC<IOAuthProps> = (props) => {
return (
<div>
<div>access token = {props.accessToken}</div>
<div>user id = {props.userID}</div>
<div>scope = {props.scope}</div>
<div>expires in = {props.expiresIn}</div>
</div>
)
}

export default OAuthFun;

现在我可以采用我的方法,它封装了规范化并返回接口(interface),并从我的父组件中使用它:

import React from 'react';
import OAuthFun, {ParseOAuthProperties, IOAuthProps} from './OAuthFun'

const App: React.FC = () => {
const props: IOAuthProps = ParseOAuthProperties(window.location.hash)
return (
<div className="App">
{/* Note, you can pass the interface wholesale with the spread operator */}
<OAuthFun {...props} />
</div>
);
}

export default App;

关于json - TypeScript:将原始数据解析为接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59597876/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com