본문 바로가기

개발하자

데이터() 키가 TypeScript와 함께 작동하도록 만드는 방법은 무엇입니까?

반응형

데이터() 키가 TypeScript와 함께 작동하도록 만드는 방법은 무엇입니까?

나는 D3에서 선택할 때 사용자 지정 키 기능을 사용하려고 합니다. 하지만, 그것을 TypeScript 호환성으로 만드는 것은 매우 힘든 일이 되고 있다.

기본적으로 D3가 인덱스를 사용하여 업데이트를 확인하기 때문에 키 기능이 없으면 요소가 제대로 제거되지 않습니다.

다음은 코드 스니펫으로 예상대로 작동합니다:

const circles = svg
        .select("g")
        .selectAll("circle")
        .data(data, d => d.val);

같은 시도를 해보니,

interface IData {
  val: number;
}

시도 1

const circles = svg
        .select("g")
        .selectAll("circle")
        .data<IData>(data, (d) => d.val);
Object d is of type 'unknown'.  TS2571

    35 |         .select("g")
    36 |         .selectAll("circle")
  > 37 |         .data<IData>(data, (d) => d.val);

시도 2

const circles = svg
        .select("g")
        .selectAll<SVGSVGElement, IData>("circle")
        .data<IData>(data, (d) => d.val);
No overload matches this call.
  Overload 1 of 3, '(data: IData[], key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
    Argument of type '(this: SVGSVGElement | Element | EnterElement | Document | Window | null, d: IData) => number' is not assignable to parameter of type 'ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string>'.
      Type 'number' is not assignable to type 'string'.
  Overload 2 of 3, '(data: ValueFn<BaseType, unknown, IData[]>, key?: ValueFn<SVGSVGElement | Element | EnterElement | Document | Window | null, IData, string> | undefined): Selection<...>', gave the following error.
    Argument of type 'IData[]' is not assignable to parameter of type 'ValueFn<BaseType, unknown, IData[]>'.
      Type 'IData[]' provides no match for the signature '(this: BaseType, datum: unknown, index: number, groups: BaseType[] | ArrayLike<BaseType>): IData[]'.  TS2769

또한 데이터에 대한 주요 기능 없이도 모두 정상적으로 작동합니다:

const circles = svg
        .select("g")
        .selectAll<SVGSVGElement, IData>("circle")
        .data<IData>(data);



키 함수에서 알 수 있듯이 문자열을 반환해야 합니다(마인 강조):

각 데이터 및 요소에 대해 기본 인덱스별 조인을 대체하여 어떤 요소에 어떤 데이터를 할당할지 제어하는 함수를 지정할 수 있습니다.

이는 다음 항목에 대해서도 확인할 수 있습니다:

data<NewDatum>(data: NewDatum[], key?: ValueFn<GElement | PElement, Datum | NewDatum, string>): Selection<GElement, NewDatum, PElement, PDatum>;

여기서 핵심 기능은 다음과 같이 정의된다

key?: ValueFn<GElement | PElement, Datum | NewDatum, string>

라는 타입으로

export type ValueFn<T extends BaseType, Datum, Result> = (this: T, datum: Datum, index: number, groups: T[] | ArrayLike<T>) => Result;

위의 두 정의를 보면 컴파일러 오류의 원인인 키 함수 정의에 대해 유형 매개 변수가 문자열로 설정되어 있음을 쉽게 알 수 있습니다.

키 함수에서 문자열을 반환하면 다음과 같은 문제가 해결됩니다:

.data(data, d => "" + d.val);



저는 리액트 + 타이프스크립트 제네릭을 사용하고 있습니다. 이제야 알았어요, 제 생각엔요. 나는 오래된 js 패턴을 사용하는 것이 컴파일러가 나중에 어떤 데이터 유형을 통과할 것인지 헷갈리는 문제에 계속 부딪혔다. 그리고 나서 나는 핵심 기능을 발견했고 그것에 대해서도 약간 어려움을 겪었다. 마지막으로, 그것은 행복해 보이고, 데이터 유형은 나중에 체인에서 일관된다. 일반 키를 내 구성 요소에 소품으로 전달하는 것이 도움이 되었다는 것을 명심하십시오. 왜냐하면 나는 값에서 키를 얻을 필요가 없기 때문입니다.

…
.data(data, () => xKey as string)

이것이 누군가에게 도움이 되었으면 좋겠어요!




내가 이 알 수 없는 오류 메시지를 우연히 만난 후에;

개체 유형이 '알 수 없음'입니다

유형을 지정하지 않고 도망칠 수 있다고 생각했어요

첫 번째 유형을 만족시켜야 할 수도 있습니다. 유형을 기록합니다

import { select } from "d3-selection";

interface INode { id: number }
let nodes: INode[] = [
    { id: 0 },
    { id: 1 },
]

select('#d3') // <div id="d3"></div>
    .selectAll<SVGSVGElement, INode>('.node') // <template class="node"></template>
    .data<INode>(nodes, d => d.id)



당신은 그것을 그렇게:

d3.selectAll<SVGCircleElement, IDataItem>, before calling .data(), where is IData = IDataItem[]

반응형