microsoft / microsoft/TypeScript
React: enforce correct usage of refs
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
Potentially a use case for #12936
if you have a problem and you think exact types are the right solution, please describe the original problem here
https://github.com/microsoft/TypeScript/issues/12936#issuecomment-284590083
Search Terms
react refs exact type
Suggestion
In React, it's fairly common to use refs. This involves creating an object of a specific type, and then passing that value as a prop to a component, which will mutate/reassign its current property.
Currently it seem there is no way to use refs in a type safe way. They can be accidentally passed to the wrong component, and there will be no type error.
https://stackoverflow.com/questions/56378639/typescript-react-enforce-correct-ref-props
import * as React from 'react';
class Modal extends React.Component<{}> {
close = () => {};
}
declare const modal: Modal;
modal.close();
const modalRef = React.createRef<Modal>();
// Let's try giving this ref to the correct component…
// No error as expected :-)
<Modal ref={modalRef} />;
class SomeOtherComponent extends React.Component<{}> {}
// Let's try giving this ref to the wrong component…
// Expected type error but got none! :-(
<SomeOtherComponent ref={modalRef} />;
IIUC, this is because ref={modalRef} is equivalent to:
declare let ref: { current: {} };
declare let modalRef: { current: { close: () => void } };
ref = modalRef;
… which will correctly not error, because modalRef is a subtype of the target type ref.
However, when we're passing a ref to a component, we want to make sure the ref argument value (modalRef) is a supertype, or exact match, of the parameter type (ref).
This is because the component is responsible for mutating the ref's current property—if we pass in a ref of the wrong type, it will be mutated to something else. Later, when we try to use the ref's current value, the value will not match the type:
// Now when we try to use this ref, TypeScript tells us it's safe to do so.
// But it's not, because the ref has been incorrectly assigned to another component!
if (modalRef.current !== null) {
modalRef.current.close(); // runtime error!
}
I am looking for a way to catch these mistakes at compile time, with TypeScript.
Note if the target component is a subtype of React.Component, we will get errors as desired:
class SomeOtherComponent extends React.Component<{}> {
foo = () => {}
}
// Let's try giving this ref to the wrong component…
// We got an error :-)
<SomeOtherComponent ref={modalRef} />;
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Es ist keine Implementierungsdatei und kein Test angegeben. Beginne damit, das verlinkte TypeScript-Issue #12936 und die React-ref-Beispiele hier zu lesen, und definiere dann einen Kompilierzeitfehler für das Übergeben eines ref an die falsche Komponente, während das Laufzeitverhalten erhalten bleibt.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- react, typescript
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 30/100